标题: STM8单片机电压表源程序 IAR环境 [打印本页]

作者: keypower    时间: 2017-4-22 11:19
标题: STM8单片机电压表源程序 IAR环境
刚刚用STM8S003做了个电压表,互相交流一下。用到了ADC采样及数码管显示。


STM8电压表单片机源程序:
  1. #include<iostm8s003f3.h>

  2. unsigned int ms_count;
  3. unsigned char adcflag;
  4. unsigned int ADCData;
  5. unsigned int tmpin;
  6. unsigned int ADCBuff[3];

  7. /*******************************************************************************
  8. **函数名称:void GPIO_Init()
  9. **功能描述:GPIO->功能引脚初始化
  10. **入口参数:无
  11. **输出:无
  12. *******************************************************************************/
  13. void GPIO_Init()
  14. {
  15.   PA_ODR &=0xf1;    //PA1,2,3置零
  16.   PA_DDR |=0x0e;    //设置端口PA1,2,3的输入输出方向寄存器为输出方向
  17.   PA_CR1 |=0x0e;     //PA1,2,3为推挽输出
  18.   PA_CR2 |=0x0e;     //PA1,2,3是输出速度最快为10MHz
  19.   
  20.   PB_ODR |=0x30;    //灭PB4,5
  21.   PB_DDR |=0x30;    //设置端口PB4,5的输入输出方向寄存器为输出方向
  22.   PB_CR1 |=0x30;     //PB4,5为推挽输出
  23.   PB_CR2 |=0x30;     //PB4,5是输出速度最快为10MHz
  24.   
  25.   PC_ODR |=0xf8;    //灭PC3,4,5,6,7
  26.   PC_DDR |=0xf8;    //设置端口PC->3,4,5,6,7的输入输出方向寄存器为输出方向
  27.   PC_CR1 |=0xf8;     //PC->3,4,5,6,7为推挽输出
  28.   PC_CR2 |=0xf8;     //PC->3,4,5,6,7是输出速度最快为10MHz
  29.   
  30.   PD_ODR |=0x02;    //灭PD1
  31.   PA_ODR &=0xe3;    //PD2,3,4置零
  32.   PD_DDR |=0x1e;    //设置端口PD->1,2,3,4的输入输出方向寄存器为输出方向
  33.   PD_CR1 |=0x1e;     //PD->1,2,3,4为推挽输出
  34.   PD_CR2 |=0x1e;     //PD->1,2,3,4是输出速度最快为10MHz
  35. }

  36. /*******************************************************************************
  37. **函数名称:void SMG_Display(int num)
  38. **功能描述:SMG显示函数
  39. **入口参数:int num
  40. **输出:无
  41. *******************************************************************************/
  42. void SMG1_Display(unsigned char num)
  43. {
  44.   switch(num)
  45.   {
  46.   case 0:
  47.       PA_ODR &=0xf1;    //PA1,2,3置零
  48.       PB_ODR |=0x30;    //PB4,5置高
  49.       PC_ODR |=0xf8;    //PC3,4,5,6,7置高
  50.       PD_ODR |=0x02;    //PD1置高
  51.         
  52.       PB_ODR &=0xcf;    //PB4,5置低a,e
  53.       PC_ODR &=0xa7;    //PC3,4,6置低c,d,f
  54.       PD_ODR &=0xfd;    //PD1置低b
  55.       //PA_ODR |=0x0e;    //GIG1,2,3置高
  56.       //PD_ODR |=0x1c;    //GIG2 2,3,4置高
  57.       break;
  58.   case 1:
  59.       PA_ODR &=0xf1;    //PA1,2,3置零
  60.       PB_ODR |=0x30;    //PB4,5置高
  61.       PC_ODR |=0xf8;    //PC3,4,5,6,7置高
  62.       PD_ODR |=0x02;    //PD1置高
  63.       
  64.       //PB_ODR &=0xcf;    //PB4,5置低a,e
  65.       PC_ODR &=0xbf;    //PC6置低c
  66.       PD_ODR &=0xfd;    //PD1置低b
  67.       //PA_ODR |=0x0e;    //GIG1,2,3置高
  68.       //PD_ODR |=0x1c;    //GIG2 2,3,4置高
  69.       break;
  70.   case 2:
  71.       PA_ODR &=0xf1;    //PA1,2,3置零
  72.       PB_ODR |=0x30;    //PB4,5置高
  73.       PC_ODR |=0xf8;    //PC3,4,5,6,7置高
  74.       PD_ODR |=0x02;    //PD1置高
  75.       
  76.       PB_ODR &=0xcf;    //PB4,5置低a,e
  77.       PC_ODR &=0x77;    //PC3,7置低d,g
  78.       PD_ODR &=0xfd;    //PD1置低b
  79.       //PA_ODR |=0x0e;    //GIG1,2,3置高
  80.       //PD_ODR |=0x1c;    //GIG2 2,3,4置高
  81.       break;
  82.   case 3:
  83.       PA_ODR &=0xf1;    //PA1,2,3置零
  84.       PB_ODR |=0x30;    //PB4,5置高
  85.       PC_ODR |=0xf8;    //PC3,4,5,6,7置高
  86.       PD_ODR |=0x02;    //PD1置高
  87.       
  88.       PB_ODR &=0xef;    //PB4置低a
  89.       PC_ODR &=0x37;    //PC3,6,7置低c,d,g
  90.       PD_ODR &=0xfd;    //PD1置低b
  91.       //PA_ODR |=0x0e;    //GIG1,2,3置高
  92.       //PD_ODR |=0x1c;    //GIG2 2,3,4置高
  93.       break;
  94.   case 4:
  95.       PA_ODR &=0xf1;    //PA1,2,3置零
  96.       PB_ODR |=0x30;    //PB4,5置高
  97.       PC_ODR |=0xf8;    //PC3,4,5,6,7置高
  98.       PD_ODR |=0x02;    //PD1置高
  99.       
  100.       //PB_ODR &=0xef;    //PB4置低a
  101.       PC_ODR &=0x2f;    //PC4,6,7置低c,f,g
  102.       PD_ODR &=0xfd;    //PD1置低b
  103.       //PA_ODR |=0x0e;    //GIG1,2,3置高
  104.       //PD_ODR |=0x1c;    //GIG2 2,3,4置高
  105.       break;
  106.   case 5:
  107.       PA_ODR &=0xf1;    //PA1,2,3置零
  108.       PB_ODR |=0x30;    //PB4,5置高
  109.       PC_ODR |=0xf8;    //PC3,4,5,6,7置高
  110.       PD_ODR |=0x02;    //PD1置高
  111.       
  112.       PB_ODR &=0xef;    //PB4置低a
  113.       PC_ODR &=0x27;    //PC3,4,6,7置低c,d,f,g
  114.       //PD_ODR &=0xfd;    //PD1置低b
  115.       //PA_ODR |=0x0e;    //GIG1,2,3置高
  116.       //PD_ODR |=0x1c;    //GIG2 2,3,4置高
  117.       break;
  118.   case 6:
  119.       PA_ODR &=0xf1;    //PA1,2,3置零
  120.       PB_ODR |=0x30;    //PB4,5置高
  121.       PC_ODR |=0xf8;    //PC3,4,5,6,7置高
  122.       PD_ODR |=0x02;    //PD1置高
  123.       
  124.       PB_ODR &=0xcf;    //PB4,5置低a,e
  125.       PC_ODR &=0x27;    //PC3,4,6,7置低c,d,f,g
  126.       //PD_ODR &=0xfd;    //PD1置低b
  127.       //PA_ODR |=0x0e;    //GIG1,2,3置高
  128.       //PD_ODR |=0x1c;    //GIG2 2,3,4置高
  129.       break;
  130.   case 7:
  131.       PA_ODR &=0xf1;    //PA1,2,3置零
  132.       PB_ODR |=0x30;    //PB4,5置高
  133.       PC_ODR |=0xf8;    //PC3,4,5,6,7置高
  134.       PD_ODR |=0x02;    //PD1置高
  135.       
  136.       PB_ODR &=0xef;    //PB4置低a
  137.       PC_ODR &=0xbf;    //PC6置低c
  138.       PD_ODR &=0xfd;    //PD1置低b
  139.       //PA_ODR |=0x0e;    //GIG1,2,3置高
  140.       //PD_ODR |=0x1c;    //GIG2 2,3,4置高
  141.       break;
  142.   case 8:
  143.       PA_ODR &=0xf1;    //PA1,2,3置零
  144.       PB_ODR |=0x30;    //PB4,5置高
  145.       PC_ODR |=0xf8;    //PC3,4,5,6,7置高
  146.       PD_ODR |=0x02;    //PD1置高
  147.       
  148.       PB_ODR &=0xcf;    //PB4,5置低a,e
  149.       PC_ODR &=0x27;    //PC3,4,6,7置低c,d,f,g
  150.       PD_ODR &=0xfd;    //PD1置低b
  151.       //PA_ODR |=0x0e;    //GIG1,2,3置高
  152.       //PD_ODR |=0x1c;    //GIG2 2,3,4置高
  153.       break;
  154.   case 9:
  155.       PA_ODR &=0xf1;    //PA1,2,3置零
  156.       PB_ODR |=0x30;    //PB4,5置高
  157.       PC_ODR |=0xf8;    //PC3,4,5,6,7置高
  158.       PD_ODR |=0x02;    //PD1置高
  159.       
  160.       PB_ODR &=0xef;    //PB4,5置低a,e
  161.       PC_ODR &=0x27;    //PC3,4,6,7置低c,d,f,g
  162.       PD_ODR &=0xfd;    //PD1置低b
  163.       //PA_ODR |=0x0e;    //GIG1,2,3置高
  164.       //PD_ODR |=0x1c;    //GIG2 2,3,4置高
  165.       break;
  166.   }
  167. }


  168. /*******************************************************************************
  169. **函数名称:void ADC_Init()
  170. **功能描述:初始化ADC
  171. **入口参数:无
  172. **输出:无
  173. *******************************************************************************/
  174. void ADC_Init()
  175. {
  176.   PD_DDR_bit.DDR5 = 0;   //设置PD->5 为输入
  177.   PD_CR1_bit.C15 = 0;    //设置为悬空输入
  178.   PD_CR2_bit.C25 = 0;    //设置中断禁止
  179.   
  180.   ADC_CR1_bit.SPSEL = 3;    //fmaster / 18 = 16MHZ / 18 = 888888HZ
  181.   ADC_CR2_bit.ALIGN = 1;    //RIGHT ALIGN
  182.   ADC_CSR_bit.CH = 5;       //SELECT AIN5
  183.   
  184.   ADC_CR1_bit.ADON = 1;     //启动ADC
  185. }


  186. /*******************************************************************************
  187. **函数名称:void ADC_Data_Read(unsigned int *AD_Value)
  188. **功能描述:读取ADC完成一次模数转换结果
  189. **入口参数:unsigned int *AD_Value
  190.             *AD_Value ->读取ADC采样数据的指针
  191. **输出:无
  192. *******************************************************************************/
  193. void ADC_Data_Read(unsigned int *AD_Value)
  194. {
  195.   ADC_CR1_bit.ADON = 1;       //启动ADC
  196.   
  197.   while(ADC_CSR_bit.EOC == 0);  //等待转换结束
  198.   *AD_Value = ADC_DRH;          //先读取高8位
  199.   *AD_Value = (unsigned int)((*AD_Value << 8) + ADC_DRL);   //高8位与低8位相加,凑成16位数据
  200. }

  201. unsigned int ProcessVoltage(unsigned int tmpin)
  202. {
  203.     unsigned long int Temp;
  204.     Temp=tmpin;
  205.     Temp*=330;
  206.     Temp/=1024;
  207.     return ((unsigned int)Temp)*11.3;
  208.    
  209. }

  210. /*******************************************************************************
  211. **函数名称:void Timer4Init()
  212. **功能描述:定时器4参数初始化
  213. **入口参数:无
  214. **输出:无
  215. *******************************************************************************/
  216. void Timer4Init()
  217. {

  218.   TIM4_IER_bit.UIE = 0;       //禁止中断
  219.   TIM4_EGR_bit.UG = 0;           
  220.   TIM4_PSCR_bit.PSC = 7;      // 设置TIM4的时钟分频系数为 128  即定时器时钟 = 16000000 /128 = 125KHZ
  221.                                                             
  222.   TIM4_ARR = 125;             // 设定TIM4产生1毫秒的计数值
  223.   TIM4_CNTR = 0x00;            // 清除TIM4计数寄存器数值
  224.    

  225.   TIM4_SR_bit.UIF = 0;        //清除中断标志
  226.   TIM4_SR_bit.TIF = 0;
  227.   TIM4_CR1_bit.CEN = 1;       //使能定时器4计数
  228.   TIM4_CR1_bit.ARPE = 1;      //使能预装载
  229.   TIM4_IER_bit.UIE = 1;       // 使能更新中断
  230. }

  231. /*******************************************************************************
  232. **函数名称:void TIM2_Init()
  233. **功能描述:定时器2参数初始化
  234. **入口参数:无
  235. **输出:无
  236. *******************************************************************************/
  237. void TIM2_Init()
  238. {
  239.   TIM2_PSCR = 0x00;     //定时器2预分频数为 1 分频,即定时器时钟 = 系统时钟 = 16MHz
  240.   TIM2_ARRH = 0x3E;     //设置1毫秒时间自动重载 16000 = 0x3e80
  241.   TIM2_ARRL = 0x80;     //

  242.   TIM2_CNTRH = 0x00;    //清除计数寄存器
  243.   TIM2_CNTRL = 0x00;    //
  244.   TIM2_SR1 = 0x00;      //清除所有的中断标志

  245. }

  246. /*******************************************************************************
  247. **函数名称:void TIM2_DelayMs(unsigned int ms)
  248. **功能描述:定时器2参进行精确延时,最小为1毫秒,最大65535
  249. **入口参数:unsigned int ms     1=< ms <= 65535
  250. **输出:无
  251. *******************************************************************************/
  252. void TIM2_DelayMs(unsigned int ms)
  253. {
  254.    
  255.     TIM2_CR1 = 0x81;        //启动定时器2开始计数
  256.     while(ms--)
  257.     {
  258.       
  259.       while( !(TIM2_SR1 & 0x01)); //等待计数是否达到1毫秒
  260.       TIM2_SR1 &= ~(0x01);  //计数完成1毫秒,清除相应的标志
  261.     }
  262.      TIM2_CR1 = 0x00;       //延时全部结束,关闭定时器2
  263. }


  264. /*******************************************************************************
  265. **函数名称:void delay(unsigned int ms)     Name: void delay(unsigned int ms)
  266. **功能描述:大概延时
  267. **入口参数:unsigned int ms   输入大概延时数值
  268. **输出:无
  269. *******************************************************************************/
  270. void delay(unsigned int ms)
  271. {
  272.   unsigned int x , y;
  273.   for(x = ms; x > 0; x--)           /*  通过一定周期循环进行延时*/
  274.     for(y = 1000 ; y > 0 ; y--);
  275. }


  276. /*    主函数    */
  277. int main(void)
  278. {
  279.   asm("sim");             //关闭系统总中断
  280.   CLK_CKDIVR = 0x00;      //CPUDIV = 1 HSIDIV = 1  内部时钟 = 16Mhz
  281.   //UART1_Init(9600);       //调用串口初始化函数,并设置波特率为9600 bps
  282.   //LED2Init();           //调用LED2初始化函数
  283.   GPIO_Init();
  284.   ADC_Init();             //调用ADC初始化函数
  285.   TIM2_Init();
  286.   Timer4Init();           //初始化定时器4
  287.   asm("rim");             //打开系统总中断
  288.   unsigned char i=0;
  289.   while(1)
  290.   {
  291.     if(adcflag == 1)                        //1秒定时时间到对使能ADC进行采样
  292.     {
  293.       asm("sim");                           //关系统总中断
  294.       ADC_Data_Read(&ADCData);              //读取ADC的采样数值
  295.       //Uart_SendString("ADC_DATA = " , 11);  //发送字符串"ADC_DATA = "
  296.       ADCBuff[2] = ProcessVoltage(ADCData) % 10;
  297.       ADCBuff[1] = ProcessVoltage(ADCData) / 10 %10;
  298.       ADCBuff[0] = ProcessVoltage(ADCData) / 100;
  299.       //ADCBuff[2] =ADCData % 10;
  300.       //ADCBuff[1] =ADCData / 10 %10;
  301.       //ADCBuff[0] = ADCData / 100;
  302.       /*ADCBuff[3] = ADCData % 10;      //转换成ASCII码
  303.       ADCBuff[2] = ADCData % 100 / 10;
  304.       ADCBuff[1] = ADCData / 100 % 10 ;
  305.       ADCBuff[0] = ADCData / 1000 ;
  306.       */
  307.       //ADCBuff[4] = 0x0d;                    //换行字符
  308.       //ADCBuff[5] = 0x0a;
  309.       //Uart_SendString(ADCBuff , 6);         //向PC机发送ADC采样数值
  310.       adcflag = 0;                          //ADC采样标志清除
  311.       asm("rim");                           //开系统总中断,准备下次ADC采样
  312.       //PC_ODR ^= 0x80;       //异或取反PC->3 ,使LED4进行周期性亮灭亮灭操作
  313.       i=0;
  314.       for(i=0;i<=100;i++)
  315.       {
  316.         SMG1_Display(ADCBuff[0]);   //显示个位
  317.         PA_ODR |=0x02;    //GIG1置高 亮第一个数码管
  318.         PC_ODR &=0xdf;    //PC5置高
  319.         TIM2_DelayMs(8);
  320.         SMG1_Display(ADCBuff[1]);   //显示十分位
  321.         PA_ODR |=0x04;    //GIG2置高 亮第二个数码管
  322.         TIM2_DelayMs(8);
  323.         SMG1_Display(ADCBuff[1]);   //显示百分位
  324.         PA_ODR |=0x08;    //GIG3置高 亮第二个数码管
  325.         TIM2_DelayMs(2);
  326.       }
  327.       i=0;
  328.       //adcflag = 0;                          //ADC采样标志清除
  329.     }
  330.   }
  331. }


  332. /**     定时器4中断服务函数       */
  333. #pragma vector = 25
  334. __interrupt void TIM4_UPDATE_IRQHandler(void)
  335. {
  336.   TIM4_SR_bit.UIF = 0;      //清除中断标志
  337.   ms_count++;
  338.   
  339.   if(ms_count >= 800)      //记录1秒时间到
  340.   {
  341.     ms_count = 0;
  342.     adcflag = 1;            //设置ADC采样标志
  343.   }
  344. }
复制代码

原理图:http://www.51hei.com/bbs/dpj-128925-1.html

作者: wwq123    时间: 2017-9-18 23:26
• 6位7段数码管电子密码锁 求哪位大
作者: 平平艳丽    时间: 2017-10-8 14:55
没币下载,等赚到币后再来下
作者: li96261    时间: 2017-10-15 10:21
学习啦!近段时间也是在学STM8.收藏啦!!!谢谢谢!!
作者: haiyhua    时间: 2017-10-18 23:18
谢谢!!.......................
作者: luohua880    时间: 2017-10-24 09:14
hao   学习了!
作者: zenghann    时间: 2017-10-28 09:28
谢谢了。
作者: 微笑的小小    时间: 2017-10-28 22:20
下载旁边怎么没有注明需要5黑币,我以为不要黑币的,就点下载了。下载下来看一下。
作者: 微笑的小小    时间: 2017-10-28 22:20
学习下
作者: atl0402    时间: 2017-12-5 21:37
终于下载了,可是并没有看到电路图,只有源码
作者: sun_248    时间: 2017-12-18 15:55
刚好需要
作者: caicaiw    时间: 2017-12-21 19:09
源程序下载了,楼主能不能提供一下电路图呢?谢谢
作者: zgc965377    时间: 2018-1-15 09:39
真的不错,很不错
作者: stn13135    时间: 2018-1-27 22:36
真的不错,很不错
作者: kabala56    时间: 2018-4-24 15:32
非常感谢,跟着学习不错。
作者: smartphone    时间: 2018-5-25 21:37
感谢提供 有需要再下载
作者: hclin    时间: 2018-5-30 11:29
源程序下载了,很不错
作者: keypower    时间: 2018-7-19 15:26
在另一个帖子里补上了原理图
作者: fly_apple    时间: 2018-11-30 20:26
正在学习stm8,没币了,先支持吧
作者: FQ967    时间: 2018-12-16 08:49
学习stm8!谢谢!
作者: Loser007    时间: 2019-1-20 14:59
楼主幸苦了
作者: 成森林    时间: 2019-3-4 08:37
谢谢楼主,我收藏了。
作者: donfly    时间: 2019-5-19 16:20
没有硬件电路图吗
作者: hujj    时间: 2019-5-19 20:17
好东西,作标记备用,需要时再来下。
作者: mrliangg    时间: 2019-6-18 11:39
没原理图阿
作者: mobicity    时间: 2019-8-27 21:45
学习啦!谢谢谢!!
作者: waerdeng    时间: 2019-9-16 19:42
voltage main.zip 只有2.83 KB, 果然没原理图阿
作者: m182892    时间: 2019-9-17 09:56
上原理图就完整了
作者: tyx623521553    时间: 2019-9-17 11:02
请问一下怎么开始入门stm8af系列单片机,第一步我要干什么?
作者: bbb168    时间: 2019-9-27 05:27
图呢
作者: qingcaodi128    时间: 2019-10-14 21:09
用寄存器写的,佩服!
作者: shenchaobiao    时间: 2019-10-14 23:28
没原理图吗?
作者: yifeid    时间: 2019-11-8 09:04
不错,方便多了
作者: bbb168    时间: 2019-11-8 09:35
谢谢分享。
作者: tian_000    时间: 2019-11-8 11:49
感谢楼主无私分享!
作者: 成森林    时间: 2019-11-16 09:03
谢谢楼主。下载了,,,,,,,。
作者: xxmxmxm    时间: 2020-3-24 08:22
下载下来看看。
作者: xxmxmxm    时间: 2020-3-24 08:37
没看到原理图,原理图在哪???
作者: 562034962    时间: 2020-3-30 00:24
量程范围多少呀   可以介绍一下吗?谢谢
作者: kailiang522    时间: 2020-5-5 17:31
币不够   怎么搞啊!!!!
作者: shenchaobiao    时间: 2020-5-5 23:01
原理图贴一下嘛
作者: kailiang522    时间: 2020-5-6 08:40
东西不错,下载下来学习学习!!!!
作者: dcc024    时间: 2020-5-13 09:51
大家多支持这个论坛,以前支持别的论坛
作者: cyrs    时间: 2021-1-25 23:12
才发现楼主的大作
作者: ccnnzz315    时间: 2021-1-27 08:48
fly_apple 发表于 2018-11-30 20:26
正在学习stm8,没币了,先支持吧

你另外一帖子在哪里啊?
作者: cyrs    时间: 2021-1-27 15:59
请问用什么软件编译烧录
作者: XDDZ1013    时间: 2021-2-12 23:58
只有源码,怎么没有电路图
作者: umer94    时间: 2021-3-26 23:14
Great Job but will be very nice if:

你好
任何人都可以使用单个ic MS83F1602制作伏安表
显示顶部电压3位7段和底部Amphere 3位7段
作者: 大漠游民    时间: 2021-3-30 19:24

没看到原理图




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1