想用msp430 g2553做一个时钟,要实现四位数码管显示小时和分钟,中间冒号每秒闪烁一次,三个按键控制调节时间,程序写了一部分,想请教下大家帮忙写下“时间”和“按键控制”部分的程序。谢谢!!!
#include <msp430g2553.h>
//宏定义======================================================================================//
#define DIO_high (P2OUT |= BIT2) //高电平 DIO ==> P1.5 (IIC总线需要三根线DIO、CLK、STB)
#define DIO_low (P2OUT &= ~BIT2) //低电平
#define CLK_high (P2OUT |= BIT1) //高电平 CLK ==> P1.4 (IIC总线需要三根线DIO、CLK、STB)
#define CLK_low (P2OUT &= ~BIT1) //低电平
#define STB_high (P2OUT |= BIT0) //高电平 STB ==> P1.2 (IIC总线需要三根线DIO、CLK、STB)
#define STB_low (P2OUT &= ~BIT0) //低电平
#define DIO_IN (P2DIR &= ~BIT2) //输入状态(DIO设为输入)
#define DIO_OUT (P2DIR |= BIT2) //输出状态
#define DIO_READ (P2IN & BIT2) //读引脚电平
//变量声明=====================================================================================//
unsigned char sec_count; //20ms计数值(记50次即到达1s)
unsigned char disp_flag; //显示刷新标志
unsigned char const num[20] = { 0x3f,
0x06,
0x5b,
0x4f,
0x66,
0x6d,
0x7d,
0x07,
0x7f,
0x6f,
}; //0~9显示代码
//==========================================================================================//
void delayms(unsigned int temp) //延时
{
unsigned int i,j;
for(j=temp;j>0;j--)
for(i=0;i<3210;i++);
}
//=========================================================================================//
void LED_ON3(void)
{
unsigned char ledcc; //闪烁三次计数
unsigned int x; //
for(ledcc=0; ledcc<6; ledcc++) //LED灯闪烁三次
{
P1OUT ^= BIT0 + BIT6; //翻转
for(x=0; x<50000; x++); //延时
}
}
//==========================================================================================//
void init_port(void)
{
P2SEL = 0X00; //P2口全部设为普通I/O口
P2DIR |= BIT2; //DIO ==> P3.5 (IIC总线需要三根线DIO、CLK、STB)
P2DIR |= BIT1; //CLK ==> P3.4 (IIC总线需要三根线DIO、CLK、STB)
P2DIR |= BIT0; //STB ==> P3.2 (IIC总线需要三根线DIO、CLK、STB)
DIO_high; //
CLK_high; //
STB_high; //初始时DIO、CLK、STB初始化时全部置“1”
P1DIR |= BIT0 + BIT6; //P1.0红 {MOD}LED,P1.6绿 {MOD}LED
P1OUT &= ~(BIT0 + BIT6); //上电时全灭
}
//写数据====================================================================================//
void send_data(unsigned char dat) //写数据
{
unsigned char j;
STB_low; //STB下降沿
for(j=0; j<8; j++) //一个字节8位数据
{
CLK_low; //CLK低电平
if((dat&0x01) == 1) //最低位为"1"
DIO_high; //输出高电平
else
DIO_low; //最低位为"0"
CLK_high; //CLK高电平
dat = dat>>1; //右移一位
}
}
//*读数据*==================================================================================//
unsigned char read_data(void) //读数据
{
unsigned char i,k; //
STB_low; //STB下降沿
DIO_high; //"读数据"需要DIO下降沿
delayms(1); //延时配合时序
for(i=0;i<8;i++) //需要读出8位数据
{
CLK_low; //CLK低电平
k = k >> 1; //k右移一位
if(DIO_READ == 0) //如果读到DIO为"0"
{
k = k & 0x7f; //最高位清0(右移8次后即为最低位)
}
else
{ //如果读到DIO为"1"
k = k | 0x80; //最高位置1(右移8次后即为最低位)
}
CLK_high; //CLK高电平
}
return(k); //返回k的值
}
//==========================================================================================//
void TM1638_init(void) //TM1638初始化
{
unsigned char i;
STB_high; //为了进入send_data()后产生"下降沿"
send_data(0x80); //关显示
STB_high; //写完数据后STB需置1
send_data(0x03); //显示模式
STB_high; //写完数据后STB需置1
send_data(0x40); //自动地址加1模式
send_data(0xc0); //上电后从起始地址00H-15H全部清零(全灭)
for(i=0; i<17; i++) //共16个单元清零(00H-15H)
{
send_data(0x00); //全灭
}
}
//==========================================================================================//
void start_disp(void)
{
unsigned int x;
STB_high; //为了进入send_data()后产生"下降沿"
send_data(0xc0); //起始地址
send_data(num[9]);send_data(num[3]); //分_L
send_data(num[5]);send_data(num[2]); //分_H
send_data(num[3]);send_data(num[1]); //时_L
send_data(num[2]);send_data(num[0]); //时_H
STB_high; //
send_data(0x8f); //开显示
for(x=0; x<50000; x++); //延时
}
//主函数==============================================================================================//
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; //停止看门狗定时器
init_port(); //I/O口初始化
LED_ON3(); //开机后红 {MOD}LED、绿 {MOD}LED一起闪烁三次
BCSCTL1 = CALBC1_1MHZ; //
DCOCTL = CALDCO_1MHZ; //上面两句将内部DCO校准至1MHz
TM1638_init(); //TM1638初始化
start_disp(); //开机显示"23:59"
CCTL0 = CCIE; //CCR0 interrupt enabled CCR0中断使能
CCR0 = 20971; //CCR0计数值为20971----> 20971/1048576 = 0.02000 s = 20ms
TACTL = TASSEL_2 + MC_1 + TACLR; //SMCLK, upmode 选SMCLK作为计数时钟,增计数模式
_BIS_SR(GIE); //Enter LPM0 w/ interrupt 进入低功耗模式0,并开总中断允许
P1OUT &= ~BIT6; //绿LED灯灭(运行时只闪烁红 {MOD}LED)
while(1) //系统主循环
{
if(disp_flag == 25) //到0.5s吗?
{
STB_high; //为了进入send_data()后产生"下降沿"
send_data(0xc0+8); //起始地址
send_data(num[9]);send_data(num[9]); //显示冒号
STB_high; //
}
if(disp_flag == 50) //到1s吗?
{
disp_flag = 0x00; //显示刷新标志清0
STB_high; //
send_data(0xc0+8); //起始地址
send_data(0x00);send_data(0x00); //清冒号(冒号灭)
STB_high; //
}
}
}
//============================================================================================//
#pragma vector=
tiMER0_A0_VECTOR // Timer A0 interrupt service routine (Timer_A0 中断服务程序)
__interrupt void Timer_A (void) //每20ms产生一次定时器中断
{
sec_count++; //计数值每20ms加1
disp_flag++; //
if(sec_count == 25) //加25次后,即到了0.5s (25 * 20ms = 500ms = 0.5s)
{
sec_count = 0x00; //计数值清0
P1OUT ^= 0x01; //Toggle P1.0 每0.5s翻转一次(即0.5s亮、0.5s灭,也即1s亮一次)
}
}
//============================================================================================//
一周热门 更多>