|
剛剛用STM8S003做了個(gè)電壓表,互相交流一下。用到了ADC采樣及數(shù)碼管顯示。
電壓表.JPG (2.19 MB, 下載次數(shù): 160)
下載附件
2017-4-22 11:15 上傳
STM8電壓表單片機(jī)源程序:
- #include<iostm8s003f3.h>
- unsigned int ms_count;
- unsigned char adcflag;
- unsigned int ADCData;
- unsigned int tmpin;
- unsigned int ADCBuff[3];
- /*******************************************************************************
- **函數(shù)名稱:void GPIO_Init()
- **功能描述:GPIO->功能引腳初始化
- **入口參數(shù):無
- **輸出:無
- *******************************************************************************/
- void GPIO_Init()
- {
- PA_ODR &=0xf1; //PA1,2,3置零
- PA_DDR |=0x0e; //設(shè)置端口PA1,2,3的輸入輸出方向寄存器為輸出方向
- PA_CR1 |=0x0e; //PA1,2,3為推挽輸出
- PA_CR2 |=0x0e; //PA1,2,3是輸出速度最快為10MHz
-
- PB_ODR |=0x30; //滅PB4,5
- PB_DDR |=0x30; //設(shè)置端口PB4,5的輸入輸出方向寄存器為輸出方向
- PB_CR1 |=0x30; //PB4,5為推挽輸出
- PB_CR2 |=0x30; //PB4,5是輸出速度最快為10MHz
-
- PC_ODR |=0xf8; //滅PC3,4,5,6,7
- PC_DDR |=0xf8; //設(shè)置端口PC->3,4,5,6,7的輸入輸出方向寄存器為輸出方向
- PC_CR1 |=0xf8; //PC->3,4,5,6,7為推挽輸出
- PC_CR2 |=0xf8; //PC->3,4,5,6,7是輸出速度最快為10MHz
-
- PD_ODR |=0x02; //滅PD1
- PA_ODR &=0xe3; //PD2,3,4置零
- PD_DDR |=0x1e; //設(shè)置端口PD->1,2,3,4的輸入輸出方向寄存器為輸出方向
- PD_CR1 |=0x1e; //PD->1,2,3,4為推挽輸出
- PD_CR2 |=0x1e; //PD->1,2,3,4是輸出速度最快為10MHz
- }
- /*******************************************************************************
- **函數(shù)名稱:void SMG_Display(int num)
- **功能描述:SMG顯示函數(shù)
- **入口參數(shù):int num
- **輸出:無
- *******************************************************************************/
- void SMG1_Display(unsigned char num)
- {
- switch(num)
- {
- case 0:
- PA_ODR &=0xf1; //PA1,2,3置零
- PB_ODR |=0x30; //PB4,5置高
- PC_ODR |=0xf8; //PC3,4,5,6,7置高
- PD_ODR |=0x02; //PD1置高
-
- PB_ODR &=0xcf; //PB4,5置低a,e
- PC_ODR &=0xa7; //PC3,4,6置低c,d,f
- PD_ODR &=0xfd; //PD1置低b
- //PA_ODR |=0x0e; //GIG1,2,3置高
- //PD_ODR |=0x1c; //GIG2 2,3,4置高
- break;
- case 1:
- PA_ODR &=0xf1; //PA1,2,3置零
- PB_ODR |=0x30; //PB4,5置高
- PC_ODR |=0xf8; //PC3,4,5,6,7置高
- PD_ODR |=0x02; //PD1置高
-
- //PB_ODR &=0xcf; //PB4,5置低a,e
- PC_ODR &=0xbf; //PC6置低c
- PD_ODR &=0xfd; //PD1置低b
- //PA_ODR |=0x0e; //GIG1,2,3置高
- //PD_ODR |=0x1c; //GIG2 2,3,4置高
- break;
- case 2:
- PA_ODR &=0xf1; //PA1,2,3置零
- PB_ODR |=0x30; //PB4,5置高
- PC_ODR |=0xf8; //PC3,4,5,6,7置高
- PD_ODR |=0x02; //PD1置高
-
- PB_ODR &=0xcf; //PB4,5置低a,e
- PC_ODR &=0x77; //PC3,7置低d,g
- PD_ODR &=0xfd; //PD1置低b
- //PA_ODR |=0x0e; //GIG1,2,3置高
- //PD_ODR |=0x1c; //GIG2 2,3,4置高
- break;
- case 3:
- PA_ODR &=0xf1; //PA1,2,3置零
- PB_ODR |=0x30; //PB4,5置高
- PC_ODR |=0xf8; //PC3,4,5,6,7置高
- PD_ODR |=0x02; //PD1置高
-
- PB_ODR &=0xef; //PB4置低a
- PC_ODR &=0x37; //PC3,6,7置低c,d,g
- PD_ODR &=0xfd; //PD1置低b
- //PA_ODR |=0x0e; //GIG1,2,3置高
- //PD_ODR |=0x1c; //GIG2 2,3,4置高
- break;
- case 4:
- PA_ODR &=0xf1; //PA1,2,3置零
- PB_ODR |=0x30; //PB4,5置高
- PC_ODR |=0xf8; //PC3,4,5,6,7置高
- PD_ODR |=0x02; //PD1置高
-
- //PB_ODR &=0xef; //PB4置低a
- PC_ODR &=0x2f; //PC4,6,7置低c,f,g
- PD_ODR &=0xfd; //PD1置低b
- //PA_ODR |=0x0e; //GIG1,2,3置高
- //PD_ODR |=0x1c; //GIG2 2,3,4置高
- break;
- case 5:
- PA_ODR &=0xf1; //PA1,2,3置零
- PB_ODR |=0x30; //PB4,5置高
- PC_ODR |=0xf8; //PC3,4,5,6,7置高
- PD_ODR |=0x02; //PD1置高
-
- PB_ODR &=0xef; //PB4置低a
- PC_ODR &=0x27; //PC3,4,6,7置低c,d,f,g
- //PD_ODR &=0xfd; //PD1置低b
- //PA_ODR |=0x0e; //GIG1,2,3置高
- //PD_ODR |=0x1c; //GIG2 2,3,4置高
- break;
- case 6:
- PA_ODR &=0xf1; //PA1,2,3置零
- PB_ODR |=0x30; //PB4,5置高
- PC_ODR |=0xf8; //PC3,4,5,6,7置高
- PD_ODR |=0x02; //PD1置高
-
- PB_ODR &=0xcf; //PB4,5置低a,e
- PC_ODR &=0x27; //PC3,4,6,7置低c,d,f,g
- //PD_ODR &=0xfd; //PD1置低b
- //PA_ODR |=0x0e; //GIG1,2,3置高
- //PD_ODR |=0x1c; //GIG2 2,3,4置高
- break;
- case 7:
- PA_ODR &=0xf1; //PA1,2,3置零
- PB_ODR |=0x30; //PB4,5置高
- PC_ODR |=0xf8; //PC3,4,5,6,7置高
- PD_ODR |=0x02; //PD1置高
-
- PB_ODR &=0xef; //PB4置低a
- PC_ODR &=0xbf; //PC6置低c
- PD_ODR &=0xfd; //PD1置低b
- //PA_ODR |=0x0e; //GIG1,2,3置高
- //PD_ODR |=0x1c; //GIG2 2,3,4置高
- break;
- case 8:
- PA_ODR &=0xf1; //PA1,2,3置零
- PB_ODR |=0x30; //PB4,5置高
- PC_ODR |=0xf8; //PC3,4,5,6,7置高
- PD_ODR |=0x02; //PD1置高
-
- PB_ODR &=0xcf; //PB4,5置低a,e
- PC_ODR &=0x27; //PC3,4,6,7置低c,d,f,g
- PD_ODR &=0xfd; //PD1置低b
- //PA_ODR |=0x0e; //GIG1,2,3置高
- //PD_ODR |=0x1c; //GIG2 2,3,4置高
- break;
- case 9:
- PA_ODR &=0xf1; //PA1,2,3置零
- PB_ODR |=0x30; //PB4,5置高
- PC_ODR |=0xf8; //PC3,4,5,6,7置高
- PD_ODR |=0x02; //PD1置高
-
- PB_ODR &=0xef; //PB4,5置低a,e
- PC_ODR &=0x27; //PC3,4,6,7置低c,d,f,g
- PD_ODR &=0xfd; //PD1置低b
- //PA_ODR |=0x0e; //GIG1,2,3置高
- //PD_ODR |=0x1c; //GIG2 2,3,4置高
- break;
- }
- }
- /*******************************************************************************
- **函數(shù)名稱:void ADC_Init()
- **功能描述:初始化ADC
- **入口參數(shù):無
- **輸出:無
- *******************************************************************************/
- void ADC_Init()
- {
- PD_DDR_bit.DDR5 = 0; //設(shè)置PD->5 為輸入
- PD_CR1_bit.C15 = 0; //設(shè)置為懸空輸入
- PD_CR2_bit.C25 = 0; //設(shè)置中斷禁止
-
- ADC_CR1_bit.SPSEL = 3; //fmaster / 18 = 16MHZ / 18 = 888888HZ
- ADC_CR2_bit.ALIGN = 1; //RIGHT ALIGN
- ADC_CSR_bit.CH = 5; //SELECT AIN5
-
- ADC_CR1_bit.ADON = 1; //啟動(dòng)ADC
- }
- /*******************************************************************************
- **函數(shù)名稱:void ADC_Data_Read(unsigned int *AD_Value)
- **功能描述:讀取ADC完成一次模數(shù)轉(zhuǎn)換結(jié)果
- **入口參數(shù):unsigned int *AD_Value
- *AD_Value ->讀取ADC采樣數(shù)據(jù)的指針
- **輸出:無
- *******************************************************************************/
- void ADC_Data_Read(unsigned int *AD_Value)
- {
- ADC_CR1_bit.ADON = 1; //啟動(dòng)ADC
-
- while(ADC_CSR_bit.EOC == 0); //等待轉(zhuǎn)換結(jié)束
- *AD_Value = ADC_DRH; //先讀取高8位
- *AD_Value = (unsigned int)((*AD_Value << 8) + ADC_DRL); //高8位與低8位相加,湊成16位數(shù)據(jù)
- }
- unsigned int ProcessVoltage(unsigned int tmpin)
- {
- unsigned long int Temp;
- Temp=tmpin;
- Temp*=330;
- Temp/=1024;
- return ((unsigned int)Temp)*11.3;
-
- }
- /*******************************************************************************
- **函數(shù)名稱:void Timer4Init()
- **功能描述:定時(shí)器4參數(shù)初始化
- **入口參數(shù):無
- **輸出:無
- *******************************************************************************/
- void Timer4Init()
- {
-
- TIM4_IER_bit.UIE = 0; //禁止中斷
- TIM4_EGR_bit.UG = 0;
- TIM4_PSCR_bit.PSC = 7; // 設(shè)置TIM4的時(shí)鐘分頻系數(shù)為 128 即定時(shí)器時(shí)鐘 = 16000000 /128 = 125KHZ
-
- TIM4_ARR = 125; // 設(shè)定TIM4產(chǎn)生1毫秒的計(jì)數(shù)值
- TIM4_CNTR = 0x00; // 清除TIM4計(jì)數(shù)寄存器數(shù)值
-
-
- TIM4_SR_bit.UIF = 0; //清除中斷標(biāo)志
- TIM4_SR_bit.TIF = 0;
- TIM4_CR1_bit.CEN = 1; //使能定時(shí)器4計(jì)數(shù)
- TIM4_CR1_bit.ARPE = 1; //使能預(yù)裝載
- TIM4_IER_bit.UIE = 1; // 使能更新中斷
- }
- /*******************************************************************************
- **函數(shù)名稱:void TIM2_Init()
- **功能描述:定時(shí)器2參數(shù)初始化
- **入口參數(shù):無
- **輸出:無
- *******************************************************************************/
- void TIM2_Init()
- {
- TIM2_PSCR = 0x00; //定時(shí)器2預(yù)分頻數(shù)為 1 分頻,即定時(shí)器時(shí)鐘 = 系統(tǒng)時(shí)鐘 = 16MHz
- TIM2_ARRH = 0x3E; //設(shè)置1毫秒時(shí)間自動(dòng)重載 16000 = 0x3e80
- TIM2_ARRL = 0x80; //
- TIM2_CNTRH = 0x00; //清除計(jì)數(shù)寄存器
- TIM2_CNTRL = 0x00; //
- TIM2_SR1 = 0x00; //清除所有的中斷標(biāo)志
-
- }
- /*******************************************************************************
- **函數(shù)名稱:void TIM2_DelayMs(unsigned int ms)
- **功能描述:定時(shí)器2參進(jìn)行精確延時(shí),最小為1毫秒,最大65535
- **入口參數(shù):unsigned int ms 1=< ms <= 65535
- **輸出:無
- *******************************************************************************/
- void TIM2_DelayMs(unsigned int ms)
- {
-
- TIM2_CR1 = 0x81; //啟動(dòng)定時(shí)器2開始計(jì)數(shù)
- while(ms--)
- {
-
- while( !(TIM2_SR1 & 0x01)); //等待計(jì)數(shù)是否達(dá)到1毫秒
- TIM2_SR1 &= ~(0x01); //計(jì)數(shù)完成1毫秒,清除相應(yīng)的標(biāo)志
- }
- TIM2_CR1 = 0x00; //延時(shí)全部結(jié)束,關(guān)閉定時(shí)器2
- }
- /*******************************************************************************
- **函數(shù)名稱:void delay(unsigned int ms) Name: void delay(unsigned int ms)
- **功能描述:大概延時(shí)
- **入口參數(shù):unsigned int ms 輸入大概延時(shí)數(shù)值
- **輸出:無
- *******************************************************************************/
- void delay(unsigned int ms)
- {
- unsigned int x , y;
- for(x = ms; x > 0; x--) /* 通過一定周期循環(huán)進(jìn)行延時(shí)*/
- for(y = 1000 ; y > 0 ; y--);
- }
- /* 主函數(shù) */
- int main(void)
- {
- asm("sim"); //關(guān)閉系統(tǒng)總中斷
- CLK_CKDIVR = 0x00; //CPUDIV = 1 HSIDIV = 1 內(nèi)部時(shí)鐘 = 16Mhz
- //UART1_Init(9600); //調(diào)用串口初始化函數(shù),并設(shè)置波特率為9600 bps
- //LED2Init(); //調(diào)用LED2初始化函數(shù)
- GPIO_Init();
- ADC_Init(); //調(diào)用ADC初始化函數(shù)
- TIM2_Init();
- Timer4Init(); //初始化定時(shí)器4
- asm("rim"); //打開系統(tǒng)總中斷
- unsigned char i=0;
- while(1)
- {
- if(adcflag == 1) //1秒定時(shí)時(shí)間到對(duì)使能ADC進(jìn)行采樣
- {
- asm("sim"); //關(guān)系統(tǒng)總中斷
- ADC_Data_Read(&ADCData); //讀取ADC的采樣數(shù)值
- //Uart_SendString("ADC_DATA = " , 11); //發(fā)送字符串"ADC_DATA = "
- ADCBuff[2] = ProcessVoltage(ADCData) % 10;
- ADCBuff[1] = ProcessVoltage(ADCData) / 10 %10;
- ADCBuff[0] = ProcessVoltage(ADCData) / 100;
- //ADCBuff[2] =ADCData % 10;
- //ADCBuff[1] =ADCData / 10 %10;
- //ADCBuff[0] = ADCData / 100;
- /*ADCBuff[3] = ADCData % 10; //轉(zhuǎn)換成ASCII碼
- ADCBuff[2] = ADCData % 100 / 10;
- ADCBuff[1] = ADCData / 100 % 10 ;
- ADCBuff[0] = ADCData / 1000 ;
- */
- //ADCBuff[4] = 0x0d; //換行字符
- //ADCBuff[5] = 0x0a;
- //Uart_SendString(ADCBuff , 6); //向PC機(jī)發(fā)送ADC采樣數(shù)值
- adcflag = 0; //ADC采樣標(biāo)志清除
- asm("rim"); //開系統(tǒng)總中斷,準(zhǔn)備下次ADC采樣
- //PC_ODR ^= 0x80; //異或取反PC->3 ,使LED4進(jìn)行周期性亮滅亮滅操作
- i=0;
- for(i=0;i<=100;i++)
- {
- SMG1_Display(ADCBuff[0]); //顯示個(gè)位
- PA_ODR |=0x02; //GIG1置高 亮第一個(gè)數(shù)碼管
- PC_ODR &=0xdf; //PC5置高
- TIM2_DelayMs(8);
- SMG1_Display(ADCBuff[1]); //顯示十分位
- PA_ODR |=0x04; //GIG2置高 亮第二個(gè)數(shù)碼管
- TIM2_DelayMs(8);
- SMG1_Display(ADCBuff[1]); //顯示百分位
- PA_ODR |=0x08; //GIG3置高 亮第二個(gè)數(shù)碼管
- TIM2_DelayMs(2);
- }
- i=0;
- //adcflag = 0; //ADC采樣標(biāo)志清除
- }
- }
- }
- /** 定時(shí)器4中斷服務(wù)函數(shù) */
- #pragma vector = 25
- __interrupt void TIM4_UPDATE_IRQHandler(void)
- {
- TIM4_SR_bit.UIF = 0; //清除中斷標(biāo)志
- ms_count++;
-
- if(ms_count >= 800) //記錄1秒時(shí)間到
- {
- ms_count = 0;
- adcflag = 1; //設(shè)置ADC采樣標(biāo)志
- }
- }
復(fù)制代碼
原理圖:http://www.torrancerestoration.com/bbs/dpj-128925-1.html
|
評(píng)分
-
查看全部評(píng)分
|