單片機源程序如下:
- /******************************************************************
- * 實驗說明:
- * 通設置系統主時鐘(MCLK=8Mhz ) 、輔助時鐘(ACLK=8Mhz )、
- * 子系統時鐘(SMCLK=8Mhz )
- ******************************************************************/
- #include <MSP430x24x.h>
- #include <string.h>
- #define uchar unsigned char
- #define uint unsigned int
- /**************定義接口************************/
- #define LCDIO P1OUT
- #define LCD1602_RS_1 P2OUT|=1
- #define LCD1602_RS_0 P2OUT&=~1
- #define LCD1602_RW_1 P2OUT|=2
- #define LCD1602_RW_0 P2OUT&=~2
- #define LCD1602_EN_1 P2OUT|=4
- #define LCD1602_EN_0 P2OUT&=~4
- #define PWM_1 P2OUT|=8
- #define PWM_0 P2OUT&=~8
- /**************定義函數************************/
- void LCD_write_command(unsigned char command);//寫入指令函數
- void LCD_write_dat( unsigned char dat);//寫入數據函數
- void LCD_set_xy( unsigned char x, unsigned char y );//設置顯示位置函數
- void LCD_dsp_char( unsigned char x,unsigned char y, char dat);//顯示一個字符函數
- void LCD_dsp_string(unsigned char X,unsigned char Y,const char *s);//顯示字符串函數
- void LCD_init(void);//初始化函數
- void delay_nms(unsigned int n);//延時函數
- void TCL5615_DAC(unsigned int Data);
- /********************************************/
- //變量定義
- unsigned char Disbuf[10],flag;
- unsigned int DAC_num = 5;
- //ADC采集函數
- void RefreshDis0(unsigned int Data0)
- {
- Disbuf[0] = 0x30 + Data0/100%10;
- Disbuf[1] = '.';
- Disbuf[2] = 0x30 + Data0/10%10;
- Disbuf[3] = 0x30 + Data0%10;
- Disbuf[4] = 'V';
- }
- //ADC采集函數
- void RefreshDis1(unsigned int Data1)
- {
- Disbuf[5] = 0x30 + Data1/100%10;
- Disbuf[6] = '.';
- Disbuf[7] = 0x30 + Data1/10%10;
- Disbuf[8] = 0x30 + Data1%10;
- Disbuf[9] = 'A';
- }
- void P25_Onclick( void )
- {
- DAC_num = 5;
- TCL5615_DAC( DAC_num ); //205 對應1.0V 410 對應2.0V 5---20mA
-
- }
- void P26_Onclick( void )
- {
- //20mA
- DAC_num = DAC_num + 10;
- if( DAC_num > 420 )
- {
- DAC_num = 420;
- }
- TCL5615_DAC( DAC_num ); //205 對應1.0V 410 對應2.0V 5---20mA
-
- }
- void P27_Onclick( void )
- {
- DAC_num = DAC_num - 5;
- if( DAC_num < 5 )
- {
- DAC_num = 5;
- }
- TCL5615_DAC( DAC_num ); //205 對應1.0V 410 對應2.0V 5---20mA
-
- }
- //電壓顯示函數
- void Display( void )
- {
- LCD_write_command( 0x80 );
- LCD_write_dat('V');
- LCD_write_dat(':');
- LCD_write_dat( Disbuf[0] );
- LCD_write_dat( Disbuf[1] );
- LCD_write_dat( Disbuf[2] );
- LCD_write_dat( Disbuf[3] );
- LCD_write_dat( Disbuf[4] );
- LCD_write_dat( ' ' );
- LCD_write_dat( ' ' );
- LCD_write_dat('I');
- LCD_write_dat(':');
- LCD_write_dat( Disbuf[5] );
- LCD_write_dat( Disbuf[6] );
- LCD_write_dat( Disbuf[7] );
- LCD_write_dat( Disbuf[8] );
- LCD_write_dat( Disbuf[9] );
- }
- void Display_Set( void )
- {
- LCD_write_command( 0x80 + 0x40 );
- LCD_write_dat( 'S' );
- LCD_write_dat( 'e' );
- LCD_write_dat( 't' );
- LCD_write_dat( ':' );
- LCD_write_dat( ' ' );
- }
- /*******延時函數************/
- void delayms(uint t)
- {
- uint i;
- while(t--)
- for(i=1330;i>0;i--);//進過參數的調整
- }
- /*******檢查忙函數*************/
- void LCD_check_busy() //實踐證明,在我的LCD1602上,檢查忙指令通過率極低,以
- { //至于不能正常使用LCD。因此我沒有再用檢查忙函數。而使
-
- P1DIR=0x00;
- LCDIO=0xff;
- LCD1602_RS_0; //要用200次循環便能完成。
- LCD1602_RW_1;
- LCD1602_EN_1;
- while(P1IN&0x80);
- LCD1602_EN_0;
- P1OUT=0x00;
- P1DIR=0xFF;
- }
- /******************************/
- /**************寫指令函數********************************/
- void LCD_write_command(unsigned char command)
- {
-
- LCD1602_RS_0;
- LCDIO=command;
- LCD1602_EN_1;
-
- LCD1602_EN_0;
- delayms(1);
-
- }
- /***************************************************/
- /****************寫數據函數************************/
- void LCD_write_dat( unsigned char dat)
- {
- LCD1602_RS_1;
- LCDIO=dat;
- LCD1602_EN_1;
-
- LCD1602_EN_0;
- delayms(1);
- LCD1602_RS_0;
- }
- /****************************************************/
- /***************設置顯示位置**************************/
- void LCD_set_xy( unsigned char x, unsigned char y )
- {
- unsigned char address;
- if (y == 1)
- address = 0x80+x;
- else if (y == 2)
- {
- address=0x80+0x40+x;
-
- }
- LCD_write_command(address);
- }
- /***************************************************/
- /****************顯示一個字符**********************/
- void LCD_dsp_char( unsigned char x,unsigned char y, char dat)
- {
- LCD_set_xy( x, y );
- LCD_write_dat(dat);
- }
- /**********************************************/
- /***************顯示字符串函數***************/
- void LCD_dsp_string(unsigned char X,unsigned char Y,const char *s)
- {
- uchar len,List;
- len=strlen(s);
- LCD_set_xy( X, Y );
- for(List=0;List<len;List++)
- LCD_write_dat(s[List]);
-
- }
- /***********************************************/
- /********** 延時**********************/
- void delay_nms(unsigned int n)
- {
- unsigned int i=0,j=0;
- for (i=n;i>0;i--)
- for (j=0;j<1;j++);
- }
- /**************************************/
- /************初始化函數****************/
- void LCD_init(void)
- {
- LCD1602_RW_0;
- LCD1602_EN_0;
- //CLEARSCREEN;//clear screen
- LCD_write_command(0x38);//set 8 bit data transmission mode
- delayms(1);
- LCD_write_command(0x38);//set 8 bit data transmission mode
- delayms(1);
- LCD_write_command(0x38);//set 8 bit data transmission mode
- delayms(1);
- LCD_write_command(0x06);//open display (enable lcd display)
- delayms(1);
- LCD_write_command(0x0C);//set lcd first display address
- delayms(1);
- LCD_write_command(0x01);//clear screen
- delayms(1);
- LCD_dsp_string(1,1," LCD TEST ");//在第一行第一列顯示"LCD TEST"
- LCD_dsp_string(1,2," SUCCSEEE! ");//在第一行第一列顯示"LCD TEST"
- delayms(500);
- LCD_write_command(0x01);//clear screen
- delayms(1);
- }
- /****************************************************/
- //ADC
- #define ADCST0 P5OUT &= ~BIT4
- #define ADCST1 P5OUT |= BIT4
- #define ADCALE0 P5OUT &= ~BIT5
- #define ADCALE1 P5OUT |= BIT5
- #define ADCEOC0 P5OUT &= ~BIT6
- #define ADCEOC1 P5OUT |= BIT6
- #define ADCOE0 P5OUT &= ~BIT7
- #define ADCOE1 P5OUT |= BIT7
- #define ADC_Channel0 P5OUT &= ~BIT0
- #define ADC_Channel1 P5OUT |= BIT0
- unsigned int ADC1;
- void ADC_START(void)
- {
- ADCALE1;
- ADCST1;
- delayms(1);
- ADCALE0;
- ADCST0;
- delayms(1);
- }
- char ADC_READ()
- {
- uchar data;
- data=0x00;
- delayms(1);
- ADCOE1;
- ADC_START();
- delayms(5);
- data=P4IN;
- ADCOE0;
- return data;
- }
- // DAC
- //=============================================================================
- #define SET_DIN do{P3OUT |= BIT0;}while(0) //串行數據輸入
- #define CLR_DIN do{P3OUT &= ~(BIT0);}while(0) //串行數據輸入
- #define SET_SCLK do{P3OUT |= BIT1;}while(0) //串行時鐘輸入
- #define CLR_SCLK do{P3OUT &= ~(BIT1);}while(0) //串行時鐘輸入
- #define SET_CS do{P3OUT |= BIT2;}while(0) //低電平有效
- #define CLR_CS do{P3OUT &= ~(BIT2);}while(0) //低電平有效
- //=============================================================================
- /*****************************************軟件延時******************************/
- #define CPU_F ((double)16000000)
- #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
- #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
- /*******************************************************************************/
- void TCL5615_DAC(unsigned int Data)
- {
- unsigned char i;
- Data <<= 6; //移除高6位,int型數據有16位,該DA是10位
- CLR_SCLK; //在片選有效前,時鐘信號要為低
- CLR_CS; //片選有效
-
-
- for(i=0;i<12;i++) //每次轉換需要10個時鐘下降沿
- {
- if(Data&0x8000) //取最高位數據,模擬串行數據
- {
- SET_DIN;
- CLR_SCLK;
- SET_SCLK;
- }
- else
- {
- CLR_DIN; //數據在時鐘上升沿到來前準備好
- CLR_SCLK;
- SET_SCLK;
- }
- Data <<= 1; //數據左移,為下一次取數據做準備
- CLR_SCLK;
- }
-
- SET_CS; //片選失效
- delayms(1);
- }
- void main(void)
- {
-
- WDTCTL=WDTPW + WDTHOLD; // 關閉看門狗
- P1DIR=0xFF; // 設置方向
- P1SEL=0; // 設置為普通I/O 口
-
- P2DIR=0x0F; // 設置方向
- // P2SEL=0; // 設置為普通I/O 口
-
- P3DIR=0xFF; // 設置方向
- //-----配合機械按鍵,啟用內部上拉電阻-----
- P2REN |= BIT5+BIT6+BIT7; //啟用P3.5內部上下拉電阻
- P2OUT |= BIT5+BIT6+BIT7; //將電阻設置為上拉
- //-----配置P3.5中斷參數-----
- P2DIR &= ~BIT5+BIT6+BIT7; // P3.5設為輸入(可省略)
- P2IES |= BIT5+BIT6+BIT7; // P3.5設為下降沿中斷
- P2IE |= BIT5+BIT6+BIT7; // 允許P3.5中斷
-
-
- P1OUT=0x00;
-
-
- P5SEL = 0x00;
- P5DIR |= BIT0+BIT4+BIT5+BIT6;
-
-
- delayms(200);
- LCD_init(); //LCD1602初始化
-
-
- /****設置AD寄存器****/
- ADC12CTL0=ADC12ON+SHT0_2;//打開AD轉換內核,參考電壓3.3V
- ADC12CTL1=SHP;
- ADC12IE=0X01;//使能中斷允許
- ADC12CTL0|=ENC;
- P6SEL|=0x01;//P6.0電壓輸入
- P6DIR = 0xFE;
- flag=0;
- ADC12CTL0|=ADC12SC;//啟動ADC轉換器
- _BIS_SR(LPM0_bits+ GIE);//進入低功耗睡眠模式
-
- while(1)
- {
- ADC1=ADC_READ();
- RefreshDis1(ADC1*2);
- Display();
- Display_Set();
-
- if(flag == 1)
- {
- ADC12CTL0|=ADC12SC;//啟動ADC轉換器
- flag=0;
-
- }
- // _BIS_SR(LPM0_bits+ GIE);//進入低功耗睡眠模式
- }
- }
- /****ADC12中斷服務****/
- #pragma vector=ADC12_VECTOR
- __interrupt void ADC12_ISR(void)
- {
- RefreshDis0(ADC12MEM0/8);
-
- flag=1;
- LPM0_EXIT;
- }
- /*
- * 名 稱:P2_IODect()
- * 功 能:判斷具體引發中斷的IO,并調用相應IO的中斷事件處理函數
- * 說 明:該函數兼容所有8個IO的檢測,請根據實際輸入IO激活“檢測代碼”。
- */
- void P2_IODect()
- {
- unsigned int Push_Key=0;
- //-----排除輸出IO的干擾后,鎖定唯一被觸發的中斷標志位-----
- Push_Key=P2IFG&(~P2DIR);
- //-----延時一段時間,避開機械抖動區域-----
- delayms(5); //消抖延時
- //----判斷按鍵狀態是否與延時前一致-----
- if((P2IN&Push_Key)==0) //如果該次按鍵確實有效
- {
- //----判斷具體哪個IO被按下,調用該IO的事件處理函數-----
- switch(Push_Key)
- {
- case BIT5: P25_Onclick(); break;
- case BIT6: P26_Onclick(); break;
- case BIT7: P27_Onclick(); break;
- default: break; //任何情況下均加上default
- }
- }
- }
- #pragma vector = PORT2_VECTOR
- __interrupt void PORT2_ISR(void)
- {
- //-----啟用Port2事件檢測函數-----
- P2_IODect(); //檢測通過,則會調用事件處理函數
- P2IFG=0; //退出中斷前必須手動清除IO口中斷標志
- }
復制代碼
所有資料51hei提供下載:
恒流源.zip
(370.56 KB, 下載次數: 95)
2020-4-27 13:07 上傳
點擊文件名下載附件
|