|
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
3BB1DV~_GR6UJ]R{PM1NCDL.png (68.98 KB, 下載次數(shù): 88)
下載附件
2019-11-20 20:23 上傳
51hei.png (43.61 KB, 下載次數(shù): 82)
下載附件
2019-11-20 21:02 上傳
單片機(jī)源程序如下:
/******************************************************************
* 實(shí)驗(yàn)說明:
* 通設(shè)置系統(tǒng)主時(shí)鐘(MCLK=8Mhz ) 、輔助時(shí)鐘(ACLK=8Mhz )、
* 子系統(tǒng)時(shí)鐘(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_EN_1 P2OUT|=2
#define LCD1602_EN_0 P2OUT&=~2
#define PWM_1 P2OUT|=8
#define PWM_0 P2OUT&=~8
/**************定義函數(shù)************************/
void LCD_write_command(unsigned char command);//寫入指令函數(shù)
void LCD_write_dat( unsigned char dat);//寫入數(shù)據(jù)函數(shù)
void LCD_set_xy( unsigned char x, unsigned char y );//設(shè)置顯示位置函數(shù)
void LCD_dsp_char( unsigned char x,unsigned char y, char dat);//顯示一個(gè)字符函數(shù)
void LCD_dsp_string(unsigned char X,unsigned char Y,const char *s);//顯示字符串函數(shù)
void LCD_init(void);//初始化函數(shù)
void delay_nms(unsigned int n);//延時(shí)函數(shù)
void TCL5615_DAC(unsigned int Data);
/********************************************/
//變量定義
unsigned char Disbuf[12],flag;
int DAC_num = 5;
unsigned char KEY_OPEN_OR_STOP_times = 1;
//ADC采集函數(shù)
void RefreshDis0(unsigned int Data0)
{
if( Data0 < 10 )
{
Disbuf[0] = 0x30 + Data0/100%10;
Disbuf[1] = '.';
Disbuf[2] = 0x30 + Data0/10%10;
Disbuf[3] = 0x30 + Data0%10;
Disbuf[4] = 'V';
}
else
{
Disbuf[0] = 0x30 + Data0/100%10;
Disbuf[2] = 0x30 + Data0/10%10;
Disbuf[1] = '.';
Disbuf[3] = 0x30 + Data0%10;
Disbuf[4] = 'V';
}
}
//ADC采集函數(shù)
void RefreshDis1(unsigned int Data1)
{
Disbuf[5] = 0x30 + Data1/100%10;
Disbuf[6] = 0x30 + Data1/10%10;
Disbuf[7] = 0x30 + Data1%10;
Disbuf[8] = 0x30;
Disbuf[9] = 'm';
Disbuf[10] = 'A';
}
void P23_Onclick( void )
{
//50mA
DAC_num = DAC_num + 10;
if( DAC_num > 420 )
{
DAC_num = 420;
}
TCL5615_DAC( DAC_num ); //205 對(duì)應(yīng)1.0V 410 對(duì)應(yīng)2.0V 5---20mA
}
void P24_Onclick( void )
{
//50mA
DAC_num = DAC_num - 10;
if( DAC_num < 5 )
{
DAC_num = 5;
}
TCL5615_DAC( DAC_num ); //205 對(duì)應(yīng)1.0V 410 對(duì)應(yīng)2.0V 5---20mA
}
void P25_Onclick( void )
{
DAC_num = 5;
TCL5615_DAC( DAC_num ); //205 對(duì)應(yīng)1.0V 410 對(duì)應(yīng)2.0V 5---20mA
}
void P26_Onclick( void )
{
//10mA
DAC_num = DAC_num + 2;
if( DAC_num > 420 )
{
DAC_num = 420;
}
TCL5615_DAC( DAC_num ); //205 對(duì)應(yīng)1.0V 410 對(duì)應(yīng)2.0V 5---20mA
}
void P27_Onclick( void )
{
//10mA
DAC_num = DAC_num - 2;
if( DAC_num < 5 )
{
DAC_num = 5;
}
TCL5615_DAC( DAC_num ); //205 對(duì)應(yīng)1.0V 410 對(duì)應(yīng)2.0V 5---20mA
}
//電壓顯示函數(shù)
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('I');
LCD_write_dat(':');
if( Disbuf[5] != 0x30 )
{
LCD_write_dat( Disbuf[5] );
}
if( Disbuf[6] != 0x30 )
{
LCD_write_dat( Disbuf[6] );
}
LCD_write_dat( Disbuf[7] );
LCD_write_dat( Disbuf[8] );
LCD_write_dat( Disbuf[9] );
LCD_write_dat( Disbuf[10] );
}
void Display_Set( void )
{
LCD_write_command( 0x80 + 0x40 );
LCD_write_dat( 'S' );
LCD_write_dat( 'e' );
LCD_write_dat( 't' );
LCD_write_dat( ':' );
if( Disbuf[5] != 0x30 )
{
LCD_write_dat( Disbuf[5] );
}
if( Disbuf[6] != 0x30 )
{
LCD_write_dat( Disbuf[6] );
}
LCD_write_dat( Disbuf[7] );
LCD_write_dat( Disbuf[8] );
LCD_write_dat( Disbuf[9] );
LCD_write_dat( Disbuf[10] );
LCD_write_dat( ' ' );
LCD_write_dat( ' ' );
LCD_write_dat( ' ' );
if( KEY_OPEN_OR_STOP_times == 1 )
{
LCD_write_dat( 'O' );
LCD_write_dat( 'P' );
LCD_write_dat( 'E' );
LCD_write_dat( 'N' );
}
if( KEY_OPEN_OR_STOP_times == 2 )
{
LCD_write_dat( 'S' );
LCD_write_dat( 'T' );
LCD_write_dat( 'O' );
LCD_write_dat( 'P' );
}
}
/*******延時(shí)函數(shù)************/
void delayms(uint t)
{
uint i;
while(t--)
for(i=1330;i>0;i--);//進(jìn)過參數(shù)的調(diào)整
}
/*******檢查忙函數(shù)*************/
void LCD_check_busy() //實(shí)踐證明,在我的LCD1602上,檢查忙指令通過率極低,以
{ //至于不能正常使用LCD。因此我沒有再用檢查忙函數(shù)。而使
P1DIR=0x00;
LCDIO=0xff;
LCD1602_RS_0; //要用200次循環(huán)便能完成。
LCD1602_EN_1;
while(P1IN&0x80);
LCD1602_EN_0;
P1OUT=0x00;
P1DIR=0xFF;
}
/******************************/
/**************寫指令函數(shù)********************************/
void LCD_write_command(unsigned char command)
{
LCD1602_RS_0;
LCDIO=command;
LCD1602_EN_1;
LCD1602_EN_0;
delayms(1);
}
/***************************************************/
/****************寫數(shù)據(jù)函數(shù)************************/
void LCD_write_dat( unsigned char dat)
{
LCD1602_RS_1;
LCDIO=dat;
LCD1602_EN_1;
LCD1602_EN_0;
delayms(1);
LCD1602_RS_0;
}
/****************************************************/
/***************設(shè)置顯示位置**************************/
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);
}
/***************************************************/
/****************顯示一個(gè)字符**********************/
void LCD_dsp_char( unsigned char x,unsigned char y, char dat)
{
LCD_set_xy( x, y );
LCD_write_dat(dat);
}
/**********************************************/
/***************顯示字符串函數(shù)***************/
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]);
}
/***********************************************/
/********** 延時(shí)**********************/
void delay_nms(unsigned int n)
{
unsigned int i=0,j=0;
for (i=n;i>0;i--)
for (j=0;j<1;j++);
}
/**************************************/
/************初始化函數(shù)****************/
void LCD_init(void)
{
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 LED_0 P5OUT &= ~BIT3
#define LED_1 P5OUT |= BIT3
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) //串行數(shù)據(jù)輸入
#define CLR_DIN do{P3OUT &= ~(BIT0);}while(0) //串行數(shù)據(jù)輸入
#define SET_SCLK do{P3OUT |= BIT1;}while(0) //串行時(shí)鐘輸入
#define CLR_SCLK do{P3OUT &= ~(BIT1);}while(0) //串行時(shí)鐘輸入
#define SET_CS do{P3OUT |= BIT2;}while(0) //低電平有效
#define CLR_CS do{P3OUT &= ~(BIT2);}while(0) //低電平有效
//=============================================================================
/*****************************************軟件延時(shí)******************************/
#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型數(shù)據(jù)有16位,該DA是10位
CLR_SCLK; //在片選有效前,時(shí)鐘信號(hào)要為低
CLR_CS; //片選有效
for(i=0;i<12;i++) //每次轉(zhuǎn)換需要10個(gè)時(shí)鐘下降沿
{
if(Data&0x8000) //取最高位數(shù)據(jù),模擬串行數(shù)據(jù)
{
SET_DIN;
CLR_SCLK;
SET_SCLK;
}
else
{
CLR_DIN; //數(shù)據(jù)在時(shí)鐘上升沿到來前準(zhǔn)備好
CLR_SCLK;
SET_SCLK;
}
Data <<= 1; //數(shù)據(jù)左移,為下一次取數(shù)據(jù)做準(zhǔn)備
CLR_SCLK;
}
SET_CS; //片選失效
delayms(1);
}
void P22_Onclick( void )
{
KEY_OPEN_OR_STOP_times++;
if( KEY_OPEN_OR_STOP_times > 2 )
{
KEY_OPEN_OR_STOP_times = 1;
}
}
void main(void)
{
WDTCTL=WDTPW + WDTHOLD; // 關(guān)閉看門狗
P1DIR=0xFF; // 設(shè)置方向
P1SEL=0; // 設(shè)置為普通I/O 口
P2DIR=0x03; // 設(shè)置方向
// P2SEL=0; // 設(shè)置為普通I/O 口
P3DIR=0xFF; // 設(shè)置方向
//-----配合機(jī)械按鍵,啟用內(nèi)部上拉電阻-----
P2REN |= BIT2+BIT3+BIT4+BIT5+BIT6+BIT7; //啟用P3.5內(nèi)部上下拉電阻
P2OUT |= BIT2+BIT3+BIT4+BIT5+BIT6+BIT7; //將電阻設(shè)置為上拉
//-----配置P3.5中斷參數(shù)-----
P2DIR &= ~BIT2+BIT3+BIT4+BIT5+BIT6+BIT7; // P3.5設(shè)為輸入(可省略)
P2IES |= BIT2+BIT3+BIT4+BIT5+BIT6+BIT7; // P3.5設(shè)為下降沿中斷
P2IE |= BIT2+BIT3+BIT4+BIT5+BIT6+BIT7; // 允許P3.5中斷
P1OUT=0x00;
P5DIR |= BIT7+BIT4+BIT5+BIT6+BIT3;
delayms(200);
LCD_init(); //LCD1602初始化
TCL5615_DAC( DAC_num );
/****設(shè)置AD寄存器****/
ADC12CTL0=ADC12ON+SHT0_2;//打開AD轉(zhuǎn)換內(nèi)核,參考電壓3.3V
ADC12CTL1=SHP;
ADC12IE=0X01;//使能中斷允許
ADC12CTL0|=ENC;
P6SEL|=0x01;//P6.0電壓輸入
P6DIR = 0xFE;
flag=0;
ADC12CTL0|=ADC12SC;//啟動(dòng)ADC轉(zhuǎn)換器
_BIS_SR(LPM0_bits+ GIE);//進(jìn)入低功耗睡眠模式
while(1)
{
if( KEY_OPEN_OR_STOP_times == 1 )
{
LED_1;
ADC1=ADC_READ();
RefreshDis0(15-((ADC1*10)+25));
Display();
Display_Set();
if(flag == 1)
{
ADC12CTL0|=ADC12SC;//啟動(dòng)ADC轉(zhuǎn)換器
flag=0;
}
}
if( KEY_OPEN_OR_STOP_times == 2 )
{
KEY_OPEN_OR_STOP_times = 2;
LED_0;
}
}
}
/****ADC12中斷服務(wù)****/
#pragma vector=ADC12_VECTOR
__interrupt void ADC12_ISR(void)
{
RefreshDis1(ADC12MEM0/8);
flag=1;
LPM0_EXIT;
}
/*
* 名 稱:P2_IODect()
* 功 能:判斷具體引發(fā)中斷的IO,并調(diào)用相應(yīng)IO的中斷事件處理函數(shù)
* 說 明:該函數(shù)兼容所有8個(gè)IO的檢測(cè),請(qǐng)根據(jù)實(shí)際輸入IO激活“檢測(cè)代碼”。
*/
void P2_IODect()
{
unsigned int Push_Key=0;
//-----排除輸出IO的干擾后,鎖定唯一被觸發(fā)的中斷標(biāo)志位-----
Push_Key=P2IFG&(~P2DIR);
//-----延時(shí)一段時(shí)間,避開機(jī)械抖動(dòng)區(qū)域-----
delayms(5); //消抖延時(shí)
//----判斷按鍵狀態(tài)是否與延時(shí)前一致-----
if((P2IN&Push_Key)==0) //如果該次按鍵確實(shí)有效
{
//----判斷具體哪個(gè)IO被按下,調(diào)用該IO的事件處理函數(shù)-----
switch(Push_Key)
{
case BIT2: P22_Onclick(); break;
case BIT3: if(KEY_OPEN_OR_STOP_times == 1) P23_Onclick(); break;
case BIT4: if(KEY_OPEN_OR_STOP_times == 1)P24_Onclick(); break;
case BIT5: if(KEY_OPEN_OR_STOP_times == 1)P25_Onclick(); break;
case BIT6: if(KEY_OPEN_OR_STOP_times == 1)P26_Onclick(); break;
case BIT7: if(KEY_OPEN_OR_STOP_times == 1)P27_Onclick(); break;
default: break; //任何情況下均加上default
}
}
}
#pragma vector = PORT2_VECTOR
__interrupt void PORT2_ISR(void)
{
//-----啟用Port2事件檢測(cè)函數(shù)-----
P2_IODect(); //檢測(cè)通過,則會(huì)調(diào)用事件處理函數(shù)
P2IFG=0; //退出中斷前必須手動(dòng)清除IO口中斷標(biāo)志
}
51hei.png (14.09 KB, 下載次數(shù): 80)
下載附件
2019-11-20 20:59 上傳
全部資料51hei下載地址:
恒流源.rar
(341.46 KB, 下載次數(shù): 80)
2019-11-20 20:24 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|