用msp430单片机设计一个16位的计数器,每次中断要输出一个脉冲,程序怎么编写

用msp430单片机设计一个16位的计数器,每次中断要输出一个脉冲,程序怎么编写,第1张

找个例程稍微改一下就好了:

void main(void)

{

WDTCTL = WDTPW + WDTHOLD; // Stop WDT

P1DIR |= BIT0; // P10 output

P1OUT &= ~BIT0;

CCTL0 = CCIE; // CCR0 interrupt enabled

CCR0 = 20000;

TACTL = TASSEL_2 + MC_1; // SMCLK, upmode

_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt

}

// Timer A0 interrupt service routine

#pragma vector=TIMERA0_VECTOR

__interrupt void Timer_A (void)

{

P1OUT |= BIT0; // set P10

_NOP();

_NOP();

_NOP();

_NOP();

_NOP();

P1OUT &= ~BIT0; // clear P10

}

首先你对单片机存储没有清楚的认识,数据在单片机内部最终都是以0、1二进制码的形式存储的,上面的等式是正确的,一个具体的数,不管它是什么进制的,经过相同的计算得到结果都是一样的,比如十进制1210=120,对应二进制就是1100

1010

=

0111

1000,这两个等式是等价的,120十进制就等于二进制的0111

1000。

至于电压采集,你用上面的等式得到数据,然后把这个数据格式化成字符串就OK了,最终传给1602的是一段字符串Char,字符串转换函数可以自己写,不想写的话也可以调用sprintf函数,具体可以百度

我以前倒是做过,不过程序还有点问题,调时间的时候容易过界,但正常走时候就正常了。开发环境用的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(); //扫描各功能键

}

}

}

以上就是关于用msp430单片机设计一个16位的计数器,每次中断要输出一个脉冲,程序怎么编写全部的内容,包括:用msp430单片机设计一个16位的计数器,每次中断要输出一个脉冲,程序怎么编写、MSP430单片机 F149 ADC12 模块程序、基于MSP430单片机的菜单程序设计思路,以及简单示例,最好C语言程序!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9297105.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存