⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 这是MSP430F449单片机利用时钟晶振得到实时时钟以及片内ad转换控制的源代码
💻 C
字号:
//       BIT 01234567
//       SEG abcdefgh
//
//         ___a___
//        |       |
//        |e      |b
//        |___f___|
//        |       |
//        |g      |c
//        |___h___| .d
//
/******************************0-9的显示段码**************************/

#include  "msp430x44x.h"
#define UINT unsigned int
#define UCHAR unsigned char
#define ADCMEM ((int*) 0x0140)  	// ADC12MEMx 定义
#define KEY1 BIT5
#define KEY2 BIT1
#define KEY3 BIT2


#define uchar unsigned char
#define uint unsigned int
#define bit0 BIT0
#define bit1 BIT1
#define bit2 BIT2
#define bit3 BIT3
#define bit4 BIT4
#define bit5 BIT5
#define bit6 BIT6
#define bit7 BIT7

#define rs   BIT0
#define rw   BIT1
#define en   BIT2
#define psb  BIT3

uchar com;


void ini_sys(void);//系统初始化
void ini_lcd(void);//液晶初始化
void check_busy(void);//lcd忙标志
void wrd(uchar dat);//写数据
void wrc(uchar cmd);//写指令
void delay (uchar n);//短延时
void ldelay(uchar n);//中延时
void long_delay(uint a);//长延时

void show_data(int  key);//显示阿拉伯数字
void show_han(uchar high,uchar low);//显示中文(字库)
void show_b_eng(int  key);//显示英文,大写
void show_s_eng(int  key);//显示英文,小写
void d_on(void);//P51 灯亮
void d_off(void);//P51 灯灭
//void show_pic();//显示图形
void Init(void);       // 系统初始化
void check_ad_busy(void);//检测ad忙标志
void ad_ce_and_xian(void);//ad测试加上显示
void show_zifu(unsigned char  *s);//显示字符串
void show_wb();//显示文本(top  lm3033 显示程序)

void display(void);//显示时间

void day_max_adj(void);//天数最大控制

void clear_lcd(void);//清屏

//const UCHAR seg[10]={0xd7,0x06,0xe3,0xa7,0x36,0xb5,0xf5,0x07,0xf7,0xb7};
const UCHAR seg[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};

//const unsigned char LCD_SEG[]={0xd7,0x06,0xe3,0xa7,0x36,0xb5,0xf5,0x07,0xf7,0xb7};
//                                 0    1    2     3    4    5   6     7   8     9


UCHAR year=6;	//2006-6-5,10:32:00
UCHAR month=6;
UCHAR day=11;
UCHAR hour=23;
UCHAR minute=59;
UCHAR second=50;

UINT day_max=32;
UINT ds_mode=0;



void main(void)
{
//	WDTCTL = WDTPW+WDTHOLD;		//Stop Watchdog Timer
//	LCDCTL = LCDON+LCD4MUX+LCDP1;	//STK LCD 4Mux, S0-S19
	BTCTL = BT_ADLY_1000 | BT_fLCD_DIV64;	//fLCD= fACLK/64,BT1 generates a 1S Int.
	IE2 |= BTIE;		//Enable Basic Timer interrupt
//	P5SEL = 0XFF;		//Common and Rxx all selected
//	LCDM10 = 0;
//	P2IES=KEY1+KEY2+KEY3;		//fall edge available
//	P2IFG = 0;
//	P2IE=KEY1+KEY2+KEY3;
        ini_sys();
        ini_lcd();
        Init();           //对ADC进行初始化
        _EINT();
	for(;;)
	{
		LPM3;
	}
}

//interrupt [BASICTIMER_VECTOR] void BT_ISP( void )
#pragma vector=BASICTIMER_VECTOR
__interrupt void BT_ISP (void)
{
	second++;
	if(second>=60)
	{
		second=0;
		minute++;
		if(minute>=60)
		{
			minute=0;
			hour++;
			if(hour>=24)
			{
				hour=0;
				day++;
				if(day>=day_max)
				{
					day=1;
					month++;
					if(month>=13)
					{
						month=1;
						year++;
						year %=100;
					}
					day_max_adj();
				}
			}
		}
	}
	display();
	ad_ce_and_xian();
}


void display(void)
{
	//显示时间
	wrc(0x80);
	show_zifu("北京时间");
	wrd(seg[hour/10]);
	wrd(seg[hour%10]);
	wrd(0x3a);
	wrd(seg[minute/10]);
	wrd(seg[minute%10]);
	wrd(0x3a);
	wrd(seg[second/10]);
	wrd(seg[second%10]);
	
	//显示年月日
	wrc(0x90);
	show_zifu("  日期  ");
	wrd(seg[year/10]);
	wrd(seg[year%10]);
	wrd(0x2d);
	wrd(seg[month/10]);
	wrd(seg[month%10]);
	wrd(0x2d);
	wrd(seg[day/10]);
	wrd(seg[day%10]);
}

/*void display(void)
{
	if(ds_mode==0)	//显示时、分、秒,普通模式
	{
		LCDM1 = seg[hour/10];
		LCDM2 = seg[hour%10];
		LCDM3 = 0x80;		//_
		LCDM4 = seg[minute/10]; 
		LCDM5 = seg[minute%10];
		LCDM6 = 0x80;
		LCDM7 = seg[second/10];
		LCDM8 = seg[second%10];
		LCDM9 = 0;
		if(LCDM1==seg[0])		//消隐
			LCDM1 = 0;
	}
	else if(ds_mode==1)	//显示年、月、日
	{
		
		LCDM9 = 0;
	}
	else if(ds_mode==2)	//显示年,调整年
	{
		LCDM1 = seg[2];
		LCDM2 = seg[0];
		LCDM3 = seg[year/10];
		LCDM4 = seg[year%10];
		LCDM5 = 0x20;
		LCDM6 = 0x20;
		LCDM7 = 0x20;
		LCDM8 = 0x20;
		LCDM9 = 0;
	}
	else if(ds_mode==3)	//显示年、月,调整月
	{
		LCDM1 = seg[year/10];
		LCDM2 = seg[year%10];
		LCDM3 = 0x20;
		LCDM4 = seg[month/10];
		LCDM5 = seg[month%10];
		LCDM6 = 0x20;
		LCDM7 = 0x20;
		LCDM8 = 0x20;
		LCDM9 = 0;
	}
	else if(ds_mode==4)	//显示年、日,调整日
	{
		LCDM1 = seg[year/10];
		LCDM2 = seg[year%10];
		LCDM3 = 0x20;
		LCDM4 = 0x20;
		LCDM5 = 0x20;
		LCDM6 = 0x20;
		LCDM7 = seg[day/10];
		LCDM8 = seg[day%10];
		LCDM9 = 0;
	}
	else if(ds_mode==5)	//显示时、秒,调整时钟
	{
		LCDM1 = seg[hour/10];
		LCDM2 = seg[hour%10];
		LCDM3 = 0x80;
		LCDM4 = 0x20;
		LCDM5 = 0x20;
		LCDM6 = 0x80;
		LCDM7 = seg[second/10];
		LCDM8 = seg[second%10];
		LCDM9 = 0;
		if(LCDM1==seg[0])		//消隐
			LCDM1 = 0;
	}
	else	//显示分、秒,调整分钟
	{
		LCDM1 = 0x20;
		LCDM2 = 0x20;
		LCDM3 = 0x80;
		LCDM4 = seg[minute/10]; 
		LCDM5 = seg[minute%10];
		LCDM6 = 0x80;
		LCDM7 = seg[second/10];
		LCDM8 = seg[second%10];
		LCDM9 = 0;
	}
}
*/


void day_max_adj(void)
{
	if(month==1)
		day_max = 32;
	else if(month==2)
		day_max = 29;
	else if(month==3)
		day_max = 32;
	else if(month==4)
		day_max = 31;
	else if(month==5)
		day_max = 32;
	else if(month==6)
		day_max = 31;
	else if(month==7)
		day_max = 32;
	else if(month==8)
		day_max = 32;
	else if(month==9)
		day_max = 31;
	else if(month==10)
		day_max = 32;
	else if(month==11)
		day_max = 31;
	else
		day_max = 32;
}

void ad_ce_and_xian(void)//ad测试加上显示 设定地址
{ 
     unsigned int i,j,k;
     int result[2];// Result[2];     	//用以保存转换结果
     for (i=0;i<2;i++)       
     {
          ADC12CTL0 |= 0x01;     	// 开始转换
          ADC12CTL0 &=~0x01;     
          for (j=0;j<=1000;j++); 	// 延时,准备触发序列中的下一次转换
     }
     while ((ADC12CTL1&0x0001)==1); 	// 等待整个序列的转换完成
     for(j = 0 ; j <2; j++) 
     {
          result[j] = ADCMEM[j];
          //显示数字
          k=result[j];
          
            switch(j)
            {
              case 0: wrc(0x88);
                      delay(10);
//                      show_han(0xb5,0xe7);
//                      show_han(0xd1,0xb9);

                      show_zifu("电压是");
                      k=k*0.6862;
                      show_data(k);                      
                      show_zifu("毫伏");
                      if(k>2000)
                      {
                          d_on();// 灯亮
                      }
//                      long_delay(40000);
//                      long_delay(40000);
//                      long_delay(40000);
                      // clear_lcd();

                      break;
                      
              case 1: wrc(0x98);
                      delay(10);
//                      show_han(0xce,0xc2);
//                      show_han(0xb6,0xc8);
                      show_zifu("温度是");
//                      b=k/100;
                      show_data(k);
//                      show_zifu(".");
//                      b=k%100;
//                      show_data(b);                      
//                      show_zifu("摄氏度");
//                      long_delay(40000);
//                      long_delay(40000);
//                      long_delay(40000);
                     
                     // clear_lcd();
                      break;
              default:break;        
            }
            
            //显示数字完
            //    while(1);
       }
//       for (i=0;i<=40000;i++);   	// 两个序列之间的一个延时
//       long_delay(40000);
       long_delay(40000);
       d_off();// 灯灭
      // ldelay(40000);
       
}

void Init(void)
{
//    WDTCTL = WDTPW + WDTHOLD; 	        // 停止Watchdog
    /* ADC12 Settings: */     
     P6SEL = 0xFF;         		// 所有P6口线均为ADC模块使用
     ADC12CTL0 &=~ 0x02;   		// 在进行设置时首先复位ADC的转换使能

                            		// 选则参考电压和输入管脚
     ADC12MCTL0  = 0x00;    		// Ref = AVss, AVcc; Input = A0
     ADC12MCTL1  = 0x8a;    		// Ref = AVss, AVcc; Input = A10
                            		// ADC12MCTL1 是最后一个转换通道
     ADC12CTL1 = 0x0202;    		// ADC12SC 位触发采样和保持
                            		// 采样脉冲由采样定时器产生
                            		// 时钟源:内部振荡器
                            		// 时钟分频: 1
                            		// 转换模式: 单通道、单次转换
     ADC12CTL0 = 0x0010+SHT0_8;    
     ADC12CTL0 |= 0x02;     		// 使能ADC转换
}


/*
//interrupt [PORT2_VECTOR] void P2_ISP( void )
#pragma vector=PORT2_VECTOR
__interrupt void P2_ISP (void)
{
	delay();
	if( (P2IN&KEY1) == 0 )
	{
		ds_mode ++;
		ds_mode %= 7;
		if(ds_mode == 1)
			ds_mode ++;
	}
	else if( (P2IN&KEY2) == 0 )
	{
		if(ds_mode==2)
		{
			year++;
			year%=100;
		}
		else if(ds_mode==3)
		{
			month++;
			if(month==13)
				month=1;
			day_max_adj();
		}
		else if(ds_mode==4)
		{
			day++;
			if(day==day_max)
				day = 1;
		}
		else if(ds_mode==5)
		{
			hour++;
			hour%=24;
		}
		else if(ds_mode==6)
		{
			minute++;
			minute%=60;
		}
	}
	else if( (P2IN&KEY3) == 0 )
	{
		if(ds_mode==0)
			{ds_mode=1;}
		else if(ds_mode==1)
			{ds_mode=0;}
		else if(ds_mode==2)
		{
			year--;
			if(year > 99)
				year = 99;
		}
		else if(ds_mode==3)
		{
			month--;
			if(month == 0)
				month = 12;
			day_max_adj();
		}
		else if(ds_mode==4)
		{
			day--;
			if(day == 0)
				day = day_max-1;
		}
		else if(ds_mode==5)
		{
			hour--;
			if(hour>23)
				hour = 23;
		}
		else if(ds_mode==6)
		{
			minute--;
			if(minute > 59)
				minute = 59;
		}
	}
	display();
	P2IFG=0;
}
*/



//显示字符串
void show_zifu(unsigned char *s)
{
    while(*s>0)
//    uchar i=0;
//    for( i=0;i<5;i++) 
      {
        wrd(*s);
        s++;
      }
}

//显示文本(top  lm3033 显示程序)
void show_wb()
{
    wrc(0x01);
    wrc(0x82);
    show_zifu("top way");
    wrc(0x88);
    show_zifu("top  lm3033 显示程序");
}

void d_on(void)//P51 灯亮
{
    P5DIR |=BIT1;
    P5OUT &=(~BIT1);
}
void d_off(void)//P51 灯灭
{
    P5DIR |=BIT1;
    P5OUT |=BIT1;
}

void show_data(int key)//显示阿拉伯数据(key)
{
    uint x;
    uint y;
    x=key%10000;
    y=x/1000;
    wrd(0x30+y);
    x=x%1000;
    y=x/100;
    wrd(0x30+y);
    x=x%100;
    y=x/10;
    wrd(0x30+y);
    x=x%10;
    wrd(0x30+x);
}                

void show_han(uchar high,uchar low)//显示中文(字库)
{
    delay(10);
    wrd(high);
    wrd(low);
}
void show_b_eng(int  key)//显示英文,大写
{
    delay(10);
    wrd(0x40+key);
}
void show_s_eng(int  key)//显示英文,小写
{
    delay(10);
    wrd(0x60+key);
}

void ini_sys(void)
{
    WDTCTL=WDTPW+WDTHOLD;  //STOP W D T
    FLL_CTL0 |= XCAP14PF;  //SET  FLL
    SCFQCTL=SCFQ_1M;
}

void ini_lcd(void)
{
//    WDTCTL=WDTPW+WDTHOLD; //STOP WDT
    P3DIR |=0XFF;//方向设置为输出
    P2DIR |=0XFF;//方向设置为输出
//    P2OUT |=BIT3;//PSB置高
    delay(100);
    com |=psb;//PSB 设置为1,通信方式设为8位
    wrc(com);
    
    delay(100);
//    com &=~(rs+rw);//设置RS   R/W为低
//    wrc(com);
//    delay(100);
    com =0x30;//功能设置-8位 基本指令集
    wrc(com);
    delay(200);
    wrc(com);
    delay(100);
    //com=0x0c;
    com =BIT3+BIT2;//显示打开  光标关  翻白显示关
    wrc(com);
    delay(200);
    com =BIT0;//清除屏幕显示  地址计数器归零
    wrc(com);
    ldelay(200);
    com =0x06;
    wrc(com);
    delay(100);
}

void check_busy(void)
{
    P2DIR =0XFF;//输出
    P3DIR =0X00;//输入
//    P3OUT =0X00;
    
    P2OUT &=~rs;//rs=0
    P2OUT |=rw;//RW=1;
    P2OUT |=en;//en=1
//    P2OUT |=BIT3;//PSB置高
    do
    {
        ;
    }
    while (P3IN>0x7f);
    
}
void wrd(uchar dat)
{
    /*
    RS=0;
    RW=1;
    P0=0XFF;
    E=1;
    */
    check_busy();
    P2DIR =0XFF;
    P3DIR =0XFF;
    P2OUT |=rs;//rs=1
    P2OUT &=~rw;//rw=0
    P3OUT =dat;//dat  数据传过去
    P2OUT |=en;//en=1;
    P2OUT &=~en;//en=0  下降沿写数据或指令
    P3OUT =0XFF;
}
void wrc(uchar cmd)
{
    check_busy();
    P2DIR =0XFF;//方向为输出
    P3DIR =0XFF;
    P2OUT &=~rs;//rs=0
    P2OUT &=~rw;//rw=0
    P3OUT =cmd;//命令传过去
    P2OUT |=en;//en=1
    P2OUT &=~en;//en=0;en下降沿写数据或指令
    P3OUT =0XFF;
    }
void delay (uchar n)
{

    while (n--);
}
void ldelay(uchar n)
{
    uchar a=100;
    while(a--)
    {
        while(n--);
    }
}

void long_delay(uint n)
{
//    uchar a=100;
//    while(a--)
//    {
        while(n--);
//    }
}
void clear_lcd(void)
{
    delay(100);
    wrc(0x01);//清屏
    delay(100);
    
}
void check_ad_busy(void)
{
    uint x;
    uint y;
    x=ADC12CTL1;
    y=x&0x0001;
    while(y==1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -