本帖最后由 zjut_zone 于 2015-4-3 12:00 编辑
- 这个程序是采集电压并用三位数码管显示的,程序方面没有系统的学习,请教程序架构改如何优化。
- <div class="blockcode"><blockquote>/* MAIN.C file
- * 电压采样并用三位数码管显示,单片机直接驱动
- */
- #include<stm8s003f3.h>
- #define N 10
- const unsigned char LED1[]={0xA8,0x28,0x98,0xB8,0x38,0xB0,0xB0,0x28,0XBF,0XBF};
- const unsigned char LED2[]={0x34,0x00,0x14,0x10,0x20,0x30,0x34,0x10,0XFF,0XFB};
- unsigned int i,k,j,value;
- unsigned int a;
- unsigned char d=0;
- unsigned int sum=0;
- unsigned char adcbuf[9];
- _Bool dot @PC_ODR:6;
- //*三位数码管显示函数*//
- void Display(unsigned char x)
- {
- for(i=0;i<200;i++);
- PC_ODR = 0X00;
- PD_ODR = 0X00;
- if(++d>2)
- {
- d=0;
- }
- //*三位数码管十位显示范围1-2*//
- if(d==0)
- {
- if(x/100==2)
- {
- PA_ODR = 0X0c; //共阴极数码管,显示第一位
- PC_ODR = LED1[2]; //显示数字2,PC和PD共同控制
- PD_ODR = LED2[2];
- }
- else if(x/100==1)
- {
- PA_ODR = 0X0c;
- PC_ODR = LED1[1];
- PD_ODR = LED2[1];
- }
- else
- {
- PA_ODR = 0X00;
- }
- }
- //*三位数码管个位显示范围0-9和小数点*//
- else if(d==1)
- {
- if(x/10%10==0)
- {
- PA_ODR = 0X0a; //共阴极数码管,显示第二位
- PC_ODR = LED1[0];
- PD_ODR = LED2[0];
- dot=1; //显示小数点
- }
- else if(x/10%10==1)
- {
- PA_ODR = 0X0a;
- PC_ODR = LED1[1];
- PD_ODR = LED2[1];
- dot=1;
- }
- else if(x/10%10==2)
- {
- PA_ODR = 0X0a;
- PC_ODR = LED1[2];
- PD_ODR = LED2[2];
- dot=1;
- }
- else if(x/10%10==3)
- {
- PA_ODR = 0X0a;
- PC_ODR = LED1[3];
- PD_ODR = LED2[3];
- dot=1;
- }
- else if(x/10%10==4)
- {
- PA_ODR = 0X0a;
- PC_ODR = LED1[4];
- PD_ODR = LED2[4];
- dot=1;
- }
- else if(x/10%10==5)
- {
- PA_ODR = 0X0a;
- PC_ODR = LED1[5];
- PD_ODR = LED2[5];
- dot=1;
- }
- else if(x/10%10==6)
- {
- PA_ODR = 0X0a;
- PC_ODR = LED1[6];
- PD_ODR = LED2[6];
- dot=1;
- }
- else if(x/10%10==7)
- {
- PA_ODR = 0X0a;
- PC_ODR = LED1[7];
- PD_ODR = LED2[7];
- dot=1;
- }
- else if(x/10%10==8)
- {
- PA_ODR = 0X0a;
- PC_ODR = LED1[8];
- PD_ODR = LED2[8];
- dot=1;
- }
- else if(x/10%10==9)
- {
- PA_ODR = 0X0a;
- PC_ODR = LED1[9];
- PD_ODR = LED2[9];
- dot=1;
- }
-
- }
- //*小数点后面显示范围0-9*//
- else
- {
- if(x%10==0)
- {
- PA_ODR = 0X06;
- PC_ODR = LED1[0];
- PD_ODR = LED2[0];
- }
- if(x%10==1)
- {
- PA_ODR = 0X06;
- PC_ODR = LED1[1];
- PD_ODR = LED2[1];
- }
- if(x%10==2)
- {
- PA_ODR = 0X06;
- PC_ODR = LED1[2];
- PD_ODR = LED2[2];
- }
- if(x%10==3)
- {
- PA_ODR = 0X06;
- PC_ODR = LED1[3];
- PD_ODR = LED2[3];
- }
- if(x%10==4)
- {
- PA_ODR = 0X06;
- PC_ODR = LED1[4];
- PD_ODR = LED2[4];
- }
- if(x%10==5)
- {
- PA_ODR = 0X06;
- PC_ODR = LED1[5];
- PD_ODR = LED2[5];
- }
- if(x%10==6)
- {
- PA_ODR = 0X06;
- PC_ODR = LED1[6];
- PD_ODR = LED2[6];
- }
- if(x%10==7)
- {
- PA_ODR = 0X06;
- PC_ODR = LED1[7];
- PD_ODR = LED2[7];
- }
- if(x%10==8)
- {
- PA_ODR = 0X06;
- PC_ODR = LED1[8];
- PD_ODR = LED2[8];
- }
- if(x%10==9)
- {
- PA_ODR = 0X06;
- PC_ODR = LED1[9];
- PD_ODR = LED2[9];
- }
- }
- }
- //*初始化ADC模块*//
- void ADC_init(void)
- {
- ADC_CSR = 0x06; // 选择AD转换通道AN6
- ADC_CR1 = 0X00; // 设置AD转换时钟1/2,1MHz;单次转换
- ADC_CR2 = 0x08; // 设置数据为右对齐
- ADC_CR3 = 0x00; // 不使用数据缓冲
- ADC_TDRL = 0X01; // 禁止施密特触发
- }
- //*初始化IO口*//
- void GPIO_init(void)
- {
- CLK_ICKR = 0X01; // 系统时钟默认内部RC16MHz;
- CLK_CKDIVR = 0X18; //系统默认8分频;
- PD_DDR = 0X34; //PD6--AN6.
- PD_CR1 = 0X3F;
- PD_CR2 = 0X00;
- PD_ODR = 0Xff;
- PC_DDR = 0XF8;
- PC_CR1 = 0XFF;
- PC_CR2 = 0X00;
- PC_ODR = 0X00;
- PA_DDR = 0X0E;
- PA_CR1 = 0XFF;
- PA_CR2 = 0X00;
- PA_ODR = 0X00;
- }
- //*采集电压多组取平均值*//
- unsigned int GetADC(void)
- {
- for(i=0;i<N;i++)
- {
- ADC_CSR &= 0x7F; //EOC位清零
- while(!(ADC_CSR & 0x86)); // 等待AD转换完成,EOC自动置1
- adcbuf[i] = ADC_DRH * 256 + ADC_DRL;
- }
- for(i=0;i<N;i++)
- {
- sum+=adcbuf[i];
- }
- sum=sum/N;
- return sum;
-
- }
- void main(void)
- {
- GPIO_init();
- ADC_init();
- while (1)
- {
-
- ADC_CR1 = 0x01; // 打开AD模块电源
- for (i = 0;i < 100;i++); // 延时
- value=GetADC();
- a =(int)(((float)value / 1023) * 5000);
- a=(int)(((float)a / 30) * 1006);
- a/=100;
- Display(a);
- }
-
- }
|