|
刚刚用STM8S003做了个电压表,互相交流一下。用到了ADC采样及数码管显示。
STM8电压表单片机源程序:
- #include<iostm8s003f3.h>
- unsigned int ms_count;
- unsigned char adcflag;
- unsigned int ADCData;
- unsigned int tmpin;
- unsigned int ADCBuff[3];
- /*******************************************************************************
- **函数名称:void GPIO_Init()
- **功能描述:GPIO->功能引脚初始化
- **入口参数:无
- **输出:无
- *******************************************************************************/
- void GPIO_Init()
- {
- PA_ODR &=0xf1; //PA1,2,3置零
- PA_DDR |=0x0e; //设置端口PA1,2,3的输入输出方向寄存器为输出方向
- PA_CR1 |=0x0e; //PA1,2,3为推挽输出
- PA_CR2 |=0x0e; //PA1,2,3是输出速度最快为10MHz
-
- PB_ODR |=0x30; //灭PB4,5
- PB_DDR |=0x30; //设置端口PB4,5的输入输出方向寄存器为输出方向
- PB_CR1 |=0x30; //PB4,5为推挽输出
- PB_CR2 |=0x30; //PB4,5是输出速度最快为10MHz
-
- PC_ODR |=0xf8; //灭PC3,4,5,6,7
- PC_DDR |=0xf8; //设置端口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; //设置端口PD->1,2,3,4的输入输出方向寄存器为输出方向
- PD_CR1 |=0x1e; //PD->1,2,3,4为推挽输出
- PD_CR2 |=0x1e; //PD->1,2,3,4是输出速度最快为10MHz
- }
- /*******************************************************************************
- **函数名称:void SMG_Display(int num)
- **功能描述:SMG显示函数
- **入口参数: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;
- }
- }
- /*******************************************************************************
- **函数名称:void ADC_Init()
- **功能描述:初始化ADC
- **入口参数:无
- **输出:无
- *******************************************************************************/
- void ADC_Init()
- {
- PD_DDR_bit.DDR5 = 0; //设置PD->5 为输入
- PD_CR1_bit.C15 = 0; //设置为悬空输入
- PD_CR2_bit.C25 = 0; //设置中断禁止
-
- 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; //启动ADC
- }
- /*******************************************************************************
- **函数名称:void ADC_Data_Read(unsigned int *AD_Value)
- **功能描述:读取ADC完成一次模数转换结果
- **入口参数:unsigned int *AD_Value
- *AD_Value ->读取ADC采样数据的指针
- **输出:无
- *******************************************************************************/
- void ADC_Data_Read(unsigned int *AD_Value)
- {
- ADC_CR1_bit.ADON = 1; //启动ADC
-
- while(ADC_CSR_bit.EOC == 0); //等待转换结束
- *AD_Value = ADC_DRH; //先读取高8位
- *AD_Value = (unsigned int)((*AD_Value << 8) + ADC_DRL); //高8位与低8位相加,凑成16位数据
- }
- unsigned int ProcessVoltage(unsigned int tmpin)
- {
- unsigned long int Temp;
- Temp=tmpin;
- Temp*=330;
- Temp/=1024;
- return ((unsigned int)Temp)*11.3;
-
- }
- /*******************************************************************************
- **函数名称:void Timer4Init()
- **功能描述:定时器4参数初始化
- **入口参数:无
- **输出:无
- *******************************************************************************/
- void Timer4Init()
- {
-
- TIM4_IER_bit.UIE = 0; //禁止中断
- TIM4_EGR_bit.UG = 0;
- TIM4_PSCR_bit.PSC = 7; // 设置TIM4的时钟分频系数为 128 即定时器时钟 = 16000000 /128 = 125KHZ
-
- TIM4_ARR = 125; // 设定TIM4产生1毫秒的计数值
- TIM4_CNTR = 0x00; // 清除TIM4计数寄存器数值
-
-
- TIM4_SR_bit.UIF = 0; //清除中断标志
- TIM4_SR_bit.TIF = 0;
- TIM4_CR1_bit.CEN = 1; //使能定时器4计数
- TIM4_CR1_bit.ARPE = 1; //使能预装载
- TIM4_IER_bit.UIE = 1; // 使能更新中断
- }
- /*******************************************************************************
- **函数名称:void TIM2_Init()
- **功能描述:定时器2参数初始化
- **入口参数:无
- **输出:无
- *******************************************************************************/
- void TIM2_Init()
- {
- TIM2_PSCR = 0x00; //定时器2预分频数为 1 分频,即定时器时钟 = 系统时钟 = 16MHz
- TIM2_ARRH = 0x3E; //设置1毫秒时间自动重载 16000 = 0x3e80
- TIM2_ARRL = 0x80; //
- TIM2_CNTRH = 0x00; //清除计数寄存器
- TIM2_CNTRL = 0x00; //
- TIM2_SR1 = 0x00; //清除所有的中断标志
-
- }
- /*******************************************************************************
- **函数名称:void TIM2_DelayMs(unsigned int ms)
- **功能描述:定时器2参进行精确延时,最小为1毫秒,最大65535
- **入口参数:unsigned int ms 1=< ms <= 65535
- **输出:无
- *******************************************************************************/
- void TIM2_DelayMs(unsigned int ms)
- {
-
- TIM2_CR1 = 0x81; //启动定时器2开始计数
- while(ms--)
- {
-
- while( !(TIM2_SR1 & 0x01)); //等待计数是否达到1毫秒
- TIM2_SR1 &= ~(0x01); //计数完成1毫秒,清除相应的标志
- }
- TIM2_CR1 = 0x00; //延时全部结束,关闭定时器2
- }
- /*******************************************************************************
- **函数名称:void delay(unsigned int ms) Name: void delay(unsigned int ms)
- **功能描述:大概延时
- **入口参数:unsigned int ms 输入大概延时数值
- **输出:无
- *******************************************************************************/
- void delay(unsigned int ms)
- {
- unsigned int x , y;
- for(x = ms; x > 0; x--) /* 通过一定周期循环进行延时*/
- for(y = 1000 ; y > 0 ; y--);
- }
- /* 主函数 */
- int main(void)
- {
- asm("sim"); //关闭系统总中断
- CLK_CKDIVR = 0x00; //CPUDIV = 1 HSIDIV = 1 内部时钟 = 16Mhz
- //UART1_Init(9600); //调用串口初始化函数,并设置波特率为9600 bps
- //LED2Init(); //调用LED2初始化函数
- GPIO_Init();
- ADC_Init(); //调用ADC初始化函数
- TIM2_Init();
- Timer4Init(); //初始化定时器4
- asm("rim"); //打开系统总中断
- unsigned char i=0;
- while(1)
- {
- if(adcflag == 1) //1秒定时时间到对使能ADC进行采样
- {
- asm("sim"); //关系统总中断
- ADC_Data_Read(&ADCData); //读取ADC的采样数值
- //Uart_SendString("ADC_DATA = " , 11); //发送字符串"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; //转换成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机发送ADC采样数值
- adcflag = 0; //ADC采样标志清除
- asm("rim"); //开系统总中断,准备下次ADC采样
- //PC_ODR ^= 0x80; //异或取反PC->3 ,使LED4进行周期性亮灭亮灭操作
- i=0;
- for(i=0;i<=100;i++)
- {
- SMG1_Display(ADCBuff[0]); //显示个位
- PA_ODR |=0x02; //GIG1置高 亮第一个数码管
- PC_ODR &=0xdf; //PC5置高
- TIM2_DelayMs(8);
- SMG1_Display(ADCBuff[1]); //显示十分位
- PA_ODR |=0x04; //GIG2置高 亮第二个数码管
- TIM2_DelayMs(8);
- SMG1_Display(ADCBuff[1]); //显示百分位
- PA_ODR |=0x08; //GIG3置高 亮第二个数码管
- TIM2_DelayMs(2);
- }
- i=0;
- //adcflag = 0; //ADC采样标志清除
- }
- }
- }
- /** 定时器4中断服务函数 */
- #pragma vector = 25
- __interrupt void TIM4_UPDATE_IRQHandler(void)
- {
- TIM4_SR_bit.UIF = 0; //清除中断标志
- ms_count++;
-
- if(ms_count >= 800) //记录1秒时间到
- {
- ms_count = 0;
- adcflag = 1; //设置ADC采样标志
- }
- }
复制代码
原理图:http://www.51hei.com/bbs/dpj-128925-1.html
|
评分
-
查看全部评分
|