MSP430系列单片机是美国德州仪器(TI)1996年开始推向市场的一种16 位超低功耗的混合信号处理器(Mixed Signal Processor)。
称之为混合信号处理器,主要是由于其针对实际应用需求,把许多模拟电路、数字电路和微处理器集成在一个芯片上,以提供“单片”解决方案。
MSP430是16位单片机,51是8位单片机
MSP430采用RISC精简指令集,单个时钟周期就可以执行一条指令,相同晶振,速度较51快12倍。
其它片上资源也是MSP较丰富。
数码单反相机就是单镜头反光数码照相机,英文缩写是SLR(Single Lens Reflex),该技术就是在胶片平面的前面以45°角安装了一片反光镜,反光镜的上方依次有毛玻璃、五棱镜目镜等,五棱镜将实像光线多次反射改变光路,将影像其送至目镜,使观景窗中所看到的影像和胶片上永远一样,也使取景范围和实际拍摄范围基本上一致。这种棱镜的独到设计使得摄影者可以从取景器中直接观察到通过镜头的影像。
MSP430系列单片机是美国德州仪器(TI)1996年开始推向市场的一种16位超低
功耗、具有精简指令集(RISC)的混合信号处理器(Mixed Signal Processor)。称之为混合信号处理器,是由于其针对实际应用需求,将多个不同功能的模拟电路、数字电路模块和微处理器集成在一个芯片上,以提供“单片机”解决方案。该系列单片机多应用于需要电池供电的便携式仪器仪表中。
相对51
MSP430系列单片机是一个16位的单片机,采用了精简指令集(RISC)结构,具有丰富的寻址方式(7 种源 *** 作数寻址、4 种目的 *** 作数寻址)、简洁的 27 条内核指令以及大量的模拟指令;大量的寄存器以及片内数据存储器都可参加多种运算;还有高效的查表处理指令。这些特点保证了可编制出高效率的源程序。
运算速度快
MSP430 系列单片机能在25MHz晶体的驱动下,实现40ns的指令周期。16位的数据宽度、40ns的指令周期以及多功能的硬件乘法器(能实现乘加运算)相配合,能实现数字信号处理的某些算法(如 FFT 等)。
超低功耗
MSP430 单片机之所以有超低的功耗,是因为其在降低芯片的电源电压和灵活而可控的运行时钟方面都有其独到之处。
首先,MSP430 系列单片机的电源电压采用的是18-36V 电压。因而可使其在1MHz 的时钟条件下运行时,芯片的电流最低会在165μA左右,RAM 保持模式下的最低功耗只有01μA。
其次,独特的时钟系统设计。在 MSP430 系列中有两个不同的时钟系统:基本时钟系统、锁频环(FLL 和FLL+)时钟系统和DCO数字振荡器时钟系统。可以只使用一个晶体振荡器(32768Hz),也可以使用两个晶体振荡器。由系统时钟系统产生 CPU 和各功能所需的时钟。并且这些时钟可以在指令的控制下,打开和关闭,从而实现对总体功耗的控制。
由于系统运行时开启的功能模块不同,即采用不同的工作模式,芯片的功耗有着显著的不同。在系统中共有一种活动模式(AM)和五种低功耗模式(LPM0~LPM4)。在实时时钟模式下,可达25μA ,在RAM 保持模式下,最低可达01μA 。
片内资源丰富
MSP430 系列单片机的各系列都集成了较丰富的片内外设。它们分别是看门狗(WDT)、模拟比较器A、定时器A0(Timer_A0)、定时器A1(Timer_A1)、定时器B0(Timer_B0)、UART、SPI、I2C、硬件乘法器、液晶驱动器、10位/12位ADC、16位Σ-Δ ADC、DMA、I/O端口、基本定时器(Basic Timer)、实时时钟(RTC)和USB控制器等若干外围模块的不同组合。其中,看门狗可以使程序失控时迅速复位;模拟比较器进行模拟电压的比较,配合定时器,可设计出A/D 转换器;16 位定时器(Timer_A 和 Timer_B)具有捕获/比较功能,大量的捕获/比较寄存器,可用于事件计数、时序发生、 PWM 等;有的器件更具有可实现异步、同步及多址访问串行通信接口可方便的实现多机通信等应用;具有较多的 I/O 端口,P0、P1、P2 端口能够接收外部上升沿或下降沿的中断输入;10/12位硬件 A/D 转换器有较高的转换速率,最高可达200kbps ,能够满足大多数数据采集应用;能直接驱动液晶多达 160 段;实现两路的 12 位 D/A 转换;硬件I2C串行总线接口实现存储器串行扩展;以及为了增加数据传输速度,而采用的DMA模块。MSP430 系列单片机的这些片内外设为系统的单片解决方案提供了极大的方便。
另外,MSP430 系列单片机的中断源较多,并且可以任意嵌套,使用时灵活方便。当系统处于省电的低功耗状态时,中断唤醒只需5μs。
方便高效的开发环境
MSP430 系列有 OTP 型、 FLASH 型和 ROM 型三种类型的器件,这些器件的开发手段不同。对于 OTP 型和 ROM 型的器件是使用仿真器开发成功之后烧写或掩膜芯片;对于 FLASH 型则有十分方便的开发调试环境,因为器件片内有 JTAG 调试接口,还有可电擦写的 FLASH 存储器,因此采用先下载程序到 FLASH 内,再在器件内通过软件控制程序的运行,由 JTAG 接口读取片内信息供设计者调试使用的方法进行开发。这种方式只需要一台 PC 机和一个 JTAG 调试器,而不需要仿真器和编程器。开发语言有汇编语言和 C 语言。[4]
编辑本段MSP430单片机家族MSP430x1xx系列
基于闪存或 ROM 的超低功耗 MCU,提供 8MIPS,工作电压为 18V - 36V,具有高达 60KB 的闪存和各种高性能模拟及智能数字外设。
超低功耗低至:
01μA RAM 保持模式 07μA 实时时钟模式 200μA/MIPS 工作模式 在 6μs 之内快速从待机模式唤醒
器件参数:
闪存选项:1KB – 60KB ROM 选项:1KB – 16KB RAM 选项:512B – 10KB GPIO 选项:14、22、48 引脚 ADC 选项:10 和 12 位斜率 SAR 其它集成外设:模拟比较器、DMA、硬件乘法器、SVS、12 位 DAC[5]
MSP430F2xx系列
基于闪存的超低功耗 MCU,在 18V - 36V 的工作电压范围内性能高达 16MIPS。包含极低功耗振荡器 (VLO)、内部上拉/下拉电阻和低引脚数选择。
超低功耗低至:
01μA RAM 保持模式 03μA 待机模式 (VLO) 07μA 实时时钟模式 220μA/MIPS 工作模式 在 1μs 之内超快速地从待机模式唤醒
器件参数:
闪存选项:1KB – 120KB RAM 选项:128B – 8KB GPIO 选项:10、16、24、32、48、64 引脚 ADC 选项:10 和 12 位斜率 SAR、16 位 Σ-Δ ADC 其它集成外设:模拟比较器、硬件乘法器、DMA、SVS、12 位 DAC、运算放大器[6]
MSP430C3xx系列
旧款的 ROM 或 OTP 器件系列,工作电压为 25V - 55V,高达 32KB ROM、4MIPS 和 FLL。
超低功耗低至:
01μA RAM 保持模式 09μA 实时时钟模式 160μA/MIPS 工作模式 在 6μs 之内快速从待机模式唤醒
器件参数:
ROM 选项:2KB – 32KB RAM 选项:512B – 1KB GPIO 选项:14、40 引脚 ADC 选项:14 位斜率 SAR 其它集成外设:LCD 控制器、硬件乘法器[7]
MSP430x4xx系列
基于 LCD 闪存或 ROM 的器件系列,提供 8-16MIPS,包含集成 LCD 控制器,工作电压为 18V-36V,具有 FLL 和 SVS。低功耗测量和医疗应用的理想选择。
超低功耗低至:
01μA RAM 保持模式 07μA 实时时钟模式 200μA/MIPS 工作模式 在 6μs 之内快速从待机模式唤醒
器件参数:
闪存/ROM 选项:4kB – 120KB RAM 选项:256B – 8KB GPIO 选项:14、32、48、56、68、72、80 引脚 ADC 选项:10 和 12 位斜率 SAR、16 位 Σ-Δ ADC 其它集成外设:LCD 控制器、模拟比较器、12 位 DAC、DMA、硬件乘法器、运算放大器、USCI 模块[8]
MSP430F5xx系列
新款基于闪存的产品系列,具有最低工作功耗,在 18V-36V 的工作电压范围内性能高达 25MIPS。包含一个用于优化功耗的创新电源管理模块。
超低功耗低至:
01μA RAM 保持模式 25μA 实时时钟模式 165μA/MIPS 工作模式 在 5μs 之内快速从待机模式唤醒
器件参数:
闪存选项:高达 256KB RAM 选项:高达 16KB ADC 选项:10 和 12 位 SAR 其它集成外设:USB、模拟比较器、DMA、硬件乘法器、RTC、USCI、12 位 DAC[9]
MSP430G2553
低电源电压范围:18v至36v。
超低功耗 运行模式: 230μA (在1MHz 频率和22V 电压条件下)
待机模式: 05μA
关闭模式(RAM 保持): 01μA
5 种节能模式
· 用于模拟信号比较功能或者斜率模数(A/D) 转换的片载比较器
· 可在不到1μs 的时间里超快速地从待机模式唤醒
· 16 位精简指令集(RISC) 架构,625ns 指令周期时间
· 带内部基准、采样与保持以及自动扫描功能的10位200-ksps 模数(A/D) 转换器
· 基本时钟模块配置
– 具有四种校准频率并高达16MHz 的内部频率· 串行板上编程,
– 内部超低功耗低频(LF) 振荡器无需外部编程电压,
– 32kHz 晶体护
– 外部数字时钟源· 具有两线制(Spy-Bi-Wire) 接口的片上仿真逻辑电路
· 两个16 位Timer_A,分别具有三个捕获/比较寄存路器
· 多达24 个支持触摸感测的I/O 引脚
我以前倒是做过,不过程序还有点问题,调时间的时候容易过界,但正常走时候就正常了。开发环境用的IAR,单片机用f149,显示用的1602的四线模式。
你自己看着改程序吧,其实我也是51上移植过去的。
悲剧了,帖不下了我帖在我博客里了啊,自己去找吧
主程序
__________________________分隔线____________________________________
#include <msp430x14xh>
#include "ds1302h"
#include "LCD1602x4_mpsh"
#define DS1302_SECOND 0x81 //时钟芯片的寄存器位置,存放时间
#define DS1302_MINUTE 0x83
#define DS1302_HOUR 0x85
#define DS1302_WEEK 0x8b
#define DS1302_DAY 0x87
#define DS1302_MONTH 0x89
#define DS1302_YEAR 0x8d
unsigned char DateString[11],TimeString[9],week_value[2],TempBuffer[7]; //
char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;
char done,count,temp,flag,up_flag,down_flag;
//unsigned int temp_value=0,temp_max=0;temp_min=0; //温度值
void DateToStr(void) //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]
{ unsigned char Year,Month,Day,Week;
Year=rtc_getyear();
Month=rtc_getmon();
Day=rtc_getdate();
Week=rtc_getday();
if(hide_year<2) //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22
{
DateString[0] = '2';
DateString[1] = '0';
DateString[2] = Year/10 + '0';
DateString[3] = Year%10 + '0';
}
else
{
DateString[0] = ' ';
DateString[1] = ' ';
DateString[2] = ' ';
DateString[3] = ' ';
}
DateString[4] = '/';
if(hide_month<2)
{
DateString[5] = Month/10 + '0';
DateString[6] = Month%10 + '0';
}
else
{
DateString[5] = ' ';
DateString[6] = ' ';
}
DateString[7] = '/';
if(hide_day<2)
{
DateString[8] = Day/10 + '0';
DateString[9] = Day%10 + '0';
}
else
{
DateString[8] = ' ';
DateString[9] = ' ';
}
if(hide_week<2)
{
week_value[0] = Week%10 + '0'; //星期的数据另外放到 week_value[]数组里,跟年,月,日的分开存放,因为等一下要在最后显示
}
else
{
week_value[0] = ' ';
}
week_value[1] = '\0';
DateString[10] = '\0'; //字符串末尾加 '\0' ,判断结束字符
}
void TimeToStr(void) //将时,分,秒数据转换成液晶显示字符放到数组 TimeString[];
{ unsigned char Hour,Minute,Second;
Hour=rtc_gethour();
Minute=rtc_getmin();
Second=rtc_getsec();
if(hide_hour<2)
{
TimeString[0] = Hour/10 + '0';
TimeString[1] = Hour%10 + '0';
}
else
{
TimeString[0] = ' ';
TimeString[1] = ' ';
}
TimeString[2] = ':';
if(hide_min<2)
{
TimeString[3] = Minute/10 + '0';
TimeString[4] = Minute%10 + '0';
}
else
{
TimeString[3] = ' ';
TimeString[4] = ' ';
}
TimeString[5] = ':';
if(hide_sec<2)
{
TimeString[6] = Second/10 + '0';
TimeString[7] = Second%10 + '0';
}
else
{
TimeString[6] = ' ';
TimeString[7] = ' ';
}
DateString[8] = '\0';
}
void show_time() //液晶显示程序
{
TimeToStr(); //时间数据转换液晶字符
DateToStr(); //日期数据转换液晶字符
// ReadTemp(); //开启温度采集程序
// temp_to_str(); //温度数据转换成液晶字符
LCD_PutStr(TempBuffer,25); //显示温度
LCD_PutStr(DateString,0); //显示日期
LCD_PutStr(week_value,15); //显示星期
LCD_PutStr(" Week",10); //在液晶上显示 字母 week
LCD_PutStr(TimeString,16); //显示时间
}
////////////////////////////////////////////////////////////////////////////
void outkey() //跳出调整模式,返回默认显示
{ unsigned char Second;
if (!(P1IN&BIT0))
{
count=0;
hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;
Second=dataread(DS1302_SECOND);
datawrite(0x8e,0x00); //写入允许
datawrite(0x80,Second&0x7f);
datawrite(0x8E,0x80); //禁止写入
done=0;//temp_max=0;sund=1;
while(!(P1IN&BIT0));
delay_nms(2);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Upkey()//升序按键
{
if(!(P1IN&BIT1))
{
switch(count)
{case 1:
temp=dataread(DS1302_SECOND); //读取秒数
temp=temp+1; //秒数加1
up_flag=1; //数据调整后更新标志
if((temp&0x7f)>0x59) //超过59秒,清零
temp=0;
break;
case 2:
temp=dataread(DS1302_MINUTE); //读取分数
temp=temp+1; //分数加1
up_flag=1;
if(temp>0x59) //超过59分,清零
temp=0;
break;
case 3:
temp=dataread(DS1302_HOUR); //读取小时数
temp=temp+1; //小时数加1
up_flag=1;
if(temp>0x23) //超过23小时,清零
temp=0;
break;
case 4:
temp=dataread(DS1302_WEEK); //读取星期数
temp=temp+1; //星期数加1
up_flag=1;
if(temp>0x7)
temp=1;
break;
case 5:
temp=dataread(DS1302_DAY); //读取日数
temp=temp+1; //日数加1
up_flag=1;
if(temp>0x31)
temp=1;
break;
case 6:
temp=dataread(DS1302_MONTH); //读取月数
temp=temp+1; //月数加1
up_flag=1;
if(temp>0x12)
temp=1;
break;
case 7:
temp=dataread(DS1302_YEAR); //读取年数
temp=temp+1; //年数加1
up_flag=1;
if(temp>0x99)
temp=0;
break;
default:break;
}
while(!(P1IN&BIT1));
delay_nms(2);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void Downkey()//降序按键
{
if(!(P1IN&BIT2))
{
switch(count)
{case 1:
temp=dataread(DS1302_SECOND); //读取秒数
temp=temp-1; //秒数减1
down_flag=1; //数据调整后更新标志
if((temp&0x7f)>0x59) //小于0秒,返回59秒
temp=0x59;
break;
case 2:
temp=dataread(DS1302_MINUTE); //读取分数
temp=temp-1; //分数减1
down_flag=1;
if(temp>0x59)
temp=0x59; //小于0秒,返回59秒
break;
case 3:
temp=dataread(DS1302_HOUR); //读取小时数
temp=temp-1; //小时数减1
down_flag=1;
if(temp==0x00)
temp=0x23;
break;
case 4:
temp=dataread(DS1302_WEEK); //读取星期数
temp=temp-1; //星期数减1
down_flag=1;
if(temp==0x00)
temp=0x07;
break;
case 5:
temp=dataread(DS1302_DAY); //读取日数
temp=temp-1; //日数减1
down_flag=1;
if(temp==0x00)
temp=0x31;
break;
case 6:
temp=dataread(DS1302_MONTH); //读取月数
temp=temp-1; //月数减1
down_flag=1;
if(temp==0x00)
temp=0x12;
break;
case 7:
temp=dataread(DS1302_YEAR); //读取年数
temp=temp-1; //年数减1
down_flag=1;
if(temp>0x99)
temp=0x99;
break;
default:break;
}
while(!(P1IN&BIT2));
delay_nms(2);
}
}
void Setkey()//模式选择按键
{
if(!(P1IN&BIT3))
{
count=count+1; //Setkey按一次,count就加1
done=1; //进入调整模式
while(!(P1IN&BIT3));
delay_nms(2);
}
}
void keydone()//按键功能执行
{ unsigned char Second;
if(flag==0) //关闭时钟,停止计时
{ datawrite(0x8e,0x00); //写入允许
temp=dataread(DS1302_SECOND);
datawrite(0x80,temp|0x80);
datawrite(0x8e,0x80); //禁止写入
flag=1;
}
Setkey(); //扫描模式切换按键
switch(count)
{
case 1:do //count=2,调整秒
{
outkey(); //扫描跳出按钮
Upkey(); //扫描加按钮
Downkey(); //扫描减按钮
if(up_flag==1||down_flag==1) //数据更新,重新写入新的数据
{
datawrite(0x8e,0x00); //写入允许
datawrite(0x80,temp|0x80); //写入新的秒数
datawrite(0x8e,0x80); //禁止写入
up_flag=0;
down_flag=0;
}
hide_sec++; //位闪计数
if(hide_sec>3)
hide_sec=0;
show_time(); //液晶显示数据
}while(count==2);break;
case 2:do //count=3,调整分
{
hide_sec=0;
outkey();
Upkey();
Downkey();
if(temp>0x60)
temp=0;
if(up_flag==1||down_flag==1)
{
datawrite(0x8e,0x00); //写入允许
datawrite(0x82,temp); //写入新的分数
datawrite(0x8e,0x80); //禁止写入
up_flag=0;
down_flag=0;
}
hide_min++;
if(hide_min>3)
hide_min=0;
show_time();
}while(count==3);break;
case 3:do //count=4,调整小时
{
hide_min=0;
outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
datawrite(0x8e,0x00); //写入允许
datawrite(0x84,temp); //写入新的小时数
datawrite(0x8e,0x80); //禁止写入
up_flag=0;
down_flag=0;
}
hide_hour++;
if(hide_hour>3)
hide_hour=0;
show_time();
}while(count==4);break;
case 4:do //count=5,调整星期
{
hide_hour=0;
outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
datawrite(0x8e,0x00); //写入允许
datawrite(0x8a,temp); //写入新的星期数
datawrite(0x8e,0x80); //禁止写入
up_flag=0;
down_flag=0;
}
hide_week++;
if(hide_week>3)
hide_week=0;
show_time();
}while(count==5);break;
case 5:do //count=6,调整日
{
hide_week=0;
outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
datawrite(0x8e,0x00); //写入允许
datawrite(0x86,temp); //写入新的日数
datawrite(0x8e,0x80); //禁止写入
up_flag=0;
down_flag=0;
}
hide_day++;
if(hide_day>3)
hide_day=0;
show_time();
}while(count==6);break;
case 6:do //count=7,调整月
{
hide_day=0;
outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
datawrite(0x8e,0x00); //写入允许
datawrite(0x88,temp); //写入新的月数
datawrite(0x8e,0x80); //禁止写入
up_flag=0;
down_flag=0;
}
hide_month++;
if(hide_month>3)
hide_month=0;
show_time();
}while(count==7);break;
case 7:do //count=8,调整年
{
hide_month=0;
outkey();
Upkey();
Downkey();
if(up_flag==1||down_flag==1)
{
datawrite(0x8e,0x00); //写入允许
datawrite(0x8c,temp); //写入新的年数
datawrite(0x8e,0x80); //禁止写入
up_flag=0;
down_flag=0;
}
hide_year++;
if(hide_year>3)
hide_year=0;
show_time();
}while(count==8);break;
case 8: count=0;hide_year=0; //count8, 跳出调整模式,返回默认显示状态
Second=dataread(0x80);
datawrite(0x8e,0x00); //写入允许
datawrite(0x80,Second&0x7f);
datawrite(0x8E,0x80); //禁止写入
done=0; //temp_max=0;sund=1;
break; //count=7,开启中断,标志位置0并退出
default:break;
}
}
////////////////////////////////////////////////////////////////////////////
void rtcinit ()
{
rtc_wp(0);
rtc_stop(0);
rtc_charger(1,1);
}
void sysinit ()
{ WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
P4OUT = 0xff;
P4DIR = 0xff;
P5OUT = 0x0f;
P5DIR = 0xf0;
P6OUT = 0xfc;
P6DIR = 0xfc;
}
void main ()
{ unsigned char temp;
sysinit ();
rtcinit ();
LCD_init(); //液晶初始化
_EINT();
while (1)
{
while(done==1)
keydone(); //进入调整模式
while(done==0)
{
temp=rtc_getsec();
delay_nms(10);
if(temp!=rtc_getsec())
show_time(); //液晶显示数据
flag=0;
Setkey(); //扫描各功能键
}
}
}
P12输出X+Y的值:P1DIR|=0X04(设P12的方向),接下来要判断x+y的值是一还是零,如果为1则P1OUT|=0x40,为零为P1OUT&=0xfb;我只知道这种麻烦的方法!
对于430单片机并不能向51单片机那样,直接定义,在430单片机集中,不能这样直接定义,一般定义#define command P1OUT,然后若让p12输出高电平写为command|=0x04,低电平写为command&=0xfb;
总之,430单片机要定义的比较多,也比较麻烦,建议看参考书!
如下
#include <msp430x14xh>
typedef unsigned int uint;
typedef unsigned char uchar;
#define BIT(x) (1 << (x))
extern const unsigned char shuzi_table[];
void Send(uchar type,uchar transdata);
/液晶控制IO的宏定义/
#define cyCS 0 //P30,片选信号
#define cySID 1 //P31,串行数据
#define cyCLK 2 //P32,同步时钟
#define cyPORT P3OUT
#define cyDDR P3DIR
/
函数名称:delay_Nus
功 能:延时N个us的时间
参 数:n--延时长度
返回值 :无
/
void delay_Nus(uint n)
{
uchar i;
for(i = n;i > 0;i--)
_NOP();
}
/
函数名称:delay_1ms
功 能:延时约1ms的时间
参 数:无
返回值 :无
/
void delay_1ms(void)
{
uchar i;
for(i = 150;i > 0;i--) _NOP();
}
/
函数名称:delay_Nms
功 能:延时N个ms的时间
参 数:无
返回值 :无
/
void delay_Nms(uint n)
{
uint i = 0;
for(i = n;i > 0;i--)
delay_1ms();
}
/
函数名称:Ini_Lcd
功 能:初始化液晶模块
参 数:无
返回值 :无
/
void Ini_Lcd(void)
{
cyDDR |= BIT(cyCLK) + BIT(cySID) + BIT(cyCS); //相应的位端口设置为输出
delay_Nms(100); //延时等待液晶完成复位
Send(0,0x30); /功能设置:一次送8位数据,基本指令集/
delay_Nus(72);
Send(0,0x02); /DDRAM地址归位/
delay_Nus(72);
Send(0,0x0c); /显示设定:开显示,不显示光标,不做当前显示位反白闪动/
delay_Nus(72);
Send(0,0x01); /清屏,将DDRAM的位址计数器调整为“00H”/
delay_Nus(72);
Send(0,0x06); /功能设置,点设定:显示字符/光标从左到右移位,DDRAM地址加1/
delay_Nus(72);
}
/
函数名称:Send
功 能:MCU向液晶模块发送1一个字节的数据
参 数:type--数据类型,0--控制命令,1--显示数据
transdata--发送的数据
返回值 :无
/
void Send(uchar type,uchar transdata)
{
uchar firstbyte = 0xf8;
uchar temp;
uchar i,j = 3;
if(type) firstbyte |= 0x02;
cyPORT |= BIT(cyCS);
cyPORT &= ~BIT(cyCLK);
while(j > 0)
{
if(j == 3) temp = firstbyte;
else if(j == 2) temp = transdata&0xf0;
else temp = (transdata << 4) & 0xf0;
for(i = 8;i > 0;i--)
{
if(temp & 0x80) cyPORT |= BIT(cySID);
else cyPORT &= ~BIT(cySID);
cyPORT |= BIT(cyCLK);
temp <<= 1;
cyPORT &= ~BIT(cyCLK);
}
//三个字节之间一定要有足够的延时,否则易出现时序问题
if(j == 3) delay_Nus(600);
else delay_Nus(200);
j--;
}
cyPORT &= ~BIT(cySID);
cyPORT &= ~BIT(cyCS);
}
/
函数名称:Clear_GDRAM
功 能:清除液晶GDRAM内部的随机数据
参 数:无
返回值 :无
/
void Clear_GDRAM(void)
{
uchar i,j,k;
Send(0,0x34); //打开扩展指令集
i = 0x80;
for(j = 0;j < 32;j++)
{
Send(0,i++);
Send(0,0x80);
for(k = 0;k < 16;k++)
{
Send(1,0x00);
}
}
i = 0x80;
for(j = 0;j < 32;j++)
{
Send(0,i++);
Send(0,0x88);
for(k = 0;k < 16;k++)
{
Send(1,0x00);
}
}
Send(0,0x30); //回到基本指令集
}
/
函数名称:Draw_PM
功 能:在整个屏幕上画一个
参 数:ptr--指向保存位置的指针
返回值 :无
/
void Draw_PM(const uchar ptr)
{
uchar i,j,k;
Send(0,0x34); //打开扩展指令集
i = 0x80;
for(j = 0;j < 32;j++)
{
Send(0,i++);
Send(0,0x80);
for(k = 0;k < 16;k++)
{
Send(1,ptr++);
}
}
i = 0x80;
for(j = 0;j < 32;j++)
{
Send(0,i++);
Send(0,0x88);
for(k = 0;k < 16;k++)
{
Send(1,ptr++);
}
}
Send(0,0x36); //打开绘图显示
Send(0,0x30); //回到基本指令集
}
/
函数名称:Draw_TX
功 能:在液晶上描绘一个1616的图形
参 数:Yaddr--Y地址,
Xaddr--X地址
dp--指向保存图形数据的指针
返回值 :无
/
void Draw_TX(uchar Yaddr,uchar Xaddr,const uchar dp)
{
uchar j;
uchar k = 0;
Send(0,0x34); //使用扩展指令集,关闭绘图显示
for(j = 0;j < 16;j++)
{
Send(0,Yaddr++); //Y地址
Send(0,Xaddr); //X地址
Send(1,dp[k++]); //送两个字节的显示数据
Send(1,dp[k++]);
}
Send(0,0x36); //打开绘图显示
Send(0,0x30); //回到基本指令集模式
}
unsigned int i=0; //声明数据类型此句放到最上面,声明为全局变量,否则在中断中无法使用
430的中断函数在IAR中这样写,不知道你用的什么编译器
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void) //定时器A的中断函数
修改后源代码:
#include <msp430x14xh> //声明库文件
unsigned int i=0; //声明数据类型
void main(void)
{
int shi,ge,m;
unsigned char seg[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//共阳数码管字型码数组
WDTCTL = WDTPW + WDTHOLD; //关看门狗
P1DIR=0XFF;
P2DIR=0XFF;
P2SEL=0X00;
P1SEL=0X00;
TACTL=TASSEL0+TACLR;//aclk辅助时钟
CCTL0 = CCIE; //使能定时器A捕捉与中断功能,CCIE=0x0010
CCR0 =32768; // 设置计数器CCR0初值
TACTL |= MC0; //设置定时器工作模式为加计数到CCR0初值
while(1)//没有循环体的无限次while循环
{
shi=i/10;
ge=i%10;
P1OUT=0x80;
P2OUT=seg[ge];
for(m=0;m<1000;m++);
P1OUT=0x40;
P2OUT=seg[shi];
for(m=0;m<1000;m++);
}
}
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void) //定时器A的中断函数
{
if(i<100)
i++;
else
i=0;
}
以上就是关于msp430和51有什么区别全部的内容,包括:msp430和51有什么区别、单片机问题。msp430g2 和51单片机有哪些区别求详细一点。、基于MSP430单片机的菜单程序设计思路,以及简单示例,最好C语言程序!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)