数码之家

 找回密码
 立即注册
搜索
查看: 227|回复: 19

[C51] 小白学51单片机,FMD辉芒微FT61F023 ADC电压表

[复制链接]
发表于 昨天 09:31 | 显示全部楼层 |阅读模式
FMD辉芒微FT61F023有10位ADC
今天测试一下搭一个简易电压表,
基准电压用的芯片内部3V  采用多次采样求平均的方法





测试值跟万用表一致
用这个IC配3位数码管就可以做成网上几块钱一个的电压表




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
发表于 昨天 09:39 | 显示全部楼层
10位有点低
回复 支持 反对

使用道具 举报

发表于 昨天 09:44 | 显示全部楼层
学习了,很有吸引力
回复 支持 反对

使用道具 举报

发表于 昨天 09:52 | 显示全部楼层
看了就顶,是我美好的品质(现在看什么都要钱啊)
回复 支持 反对

使用道具 举报

发表于 昨天 10:25 | 显示全部楼层
那个地方买的板子啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 10:35 | 显示全部楼层
17805352 发表于 2025-4-30 10:25
那个地方买的板子啊

自己画的板,把IO口引出来方便搭电路测试
回复 支持 反对

使用道具 举报

发表于 昨天 11:03 | 显示全部楼层
想学单片机 代码一行都看不懂
回复 支持 反对

使用道具 举报

发表于 昨天 14:27 | 显示全部楼层
FMD辉芒微 烧录器调试器贵啊
回复 支持 反对

使用道具 举报

发表于 昨天 18:03 | 显示全部楼层
佩服,能分享源程序学习么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 20:10 | 显示全部楼层
youlinys 发表于 2025-4-30 14:27
FMD辉芒微 烧录器调试器贵啊

还好,网上买的,60多块钱
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 20:11 | 显示全部楼层
banguangan 发表于 2025-4-30 18:03
佩服,能分享源程序学习么?

晚一点上传代码,这个小 电脑太不方便了,
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 20:14 | 显示全部楼层
ADC部分
  1. #include "SYSCFG.h"
  2. #include "delay.h"

  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define ulong unsigned long

  6. uint res=0;  //

  7. //ADC初始化
  8. void ADC_INITIAL (void)
  9. {
  10.     ANSEL = 0B00000100;   //1->关闭上下拉及数字输入
  11.                           //使能AN2为模拟输入          
  12.         ADCON1 = 0B01100000;
  13.     //bit7 DIVS ADC分频时钟源 0->sysclk 1->LIRC
  14.     //bit[6:4] ADC转换时钟 110->sysclk/64
  15.    
  16.         ADCON0 = 0B11001001;
  17.     //Bit7:                ADFM=1,结果右对齐 0左对齐                    
  18.         //Bit[6:5]: VCFG参考电压
  19.     //                        00-参考电压VDD
  20.         //                        01-参考电压内部2V
  21.     //                        10-参考电压内部3V
  22.         //                        11-参考电压Vref
  23.         //Bit[4:2]:        CHS=010-选择AN2通道
  24.         //Bit1:                GO/DONE,AD转换状态位1启动转换 0转换完成
  25.         //Bit0:                ADC使能 1开 0关
  26.    
  27.         delay_us(200);  //打开ADC模块后,需等待ADC稳定时间Tst(~15us);当选择内部参考电压时需等待内部参考电压的稳定时间Tvrint(~450us)
  28.     delay_us(200);        
  29.     delay_us(50);        
  30. }                     

  31. //读取通道ADC值
  32. uint GET_ADC_DATA (uchar AN_CH)
  33. {

  34.         uchar        ADCON0_buff;  //ADCN0参数缓冲
  35.         uint        ADC_value = 0;  //ADC值
  36.         uint        ADC_DATA=0;  //ADC数据
  37.          
  38.         ADCON0_buff = ADCON0 & 0B11100011;//清空通道值 bit[4:2]000

  39.         AN_CH <<=2;   //2通道为010 左移2位为 01000           
  40.         ADCON0_buff |=  AN_CH;   //Bit[4:2]:CHS=010,选择AN2通道      

  41.         ADCON0 = ADCON0_buff;         //重新加载通道值
  42.     delay_us(2);      
  43.     //TACQ延时2us,外部串联电阻小于21kΩ
  44.     //TACQ延时4us,外部串联电阻43kΩ
  45.     //TACQ时间:必做,通道切换到GO/DONE置1的时间,保证内部 ADC 输入电容充满。
  46.     //TACQ > 0.09*(R+1)us;R为外部串联电阻(kΩ),串联电阻越小越好,最大不要超过50kΩ
  47.    
  48.         GO_DONE = 1;    //启动ADC
  49.                    //采样保持时间Tsysclk/N (N=2 for 2T,4 for 4T)
  50.     NOP();  
  51.     NOP();                              
  52.         while( GO_DONE==1 );           //等待ADC转换完成
  53.     //从GO_DONE = 1 ---> GO_DONE = 0,转换过程需要13.5TAD ~14.5TAD
  54.     //TAD(us)与转换时钟Fosc/ADCS[2:0]有关
  55.    
  56.         ADC_DATA =  ADRESH;  //ADC结果高8位
  57.         ADC_DATA <<=8;  //左移8位,准备或上ADC结果低8位
  58.         ADC_DATA |= ADRESL;   //或上ADC结果低8位 10Bit ADC整合
  59.         ADC_value =  ADC_DATA;
  60.    
  61.         return  ADC_value;  //返回ADC值
  62. }

  63. //ADC转换
  64. void ADC_convert(uchar chn)
  65. {
  66.         uchar j=0;
  67.     uint k=0;  //定义变量
  68.         for(j=0;j<30;j++)   //循环测30次
  69.     {
  70.                 k=k+GET_ADC_DATA (chn);  //累加
  71.     }
  72.     res=(k*10UL)/1024;  //转换成显示电压
  73.         //参考电压是3V 100倍就是300 上面测了30次,这里只要10倍
  74. }

复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 20:15 | 显示全部楼层
显示部分
  1. #include "SYSCFG.h"
  2. #include "lcd12232.h"
  3. #include "jishi.h"
  4. #include "ADC.h"

  5. uchar table1[ ]={"2025-  -  week "};        //要显示的字符
  6. uchar table2[ ]={"0123456789"};        //要显示的数字
  7. uchar time_num[ ]={"00:00:00 0.00V"};  //显示时间及电压

  8. void lcd_display (void)
  9. {
  10.     uchar k,j;        //声明变量,用于循环显示字符
  11.     table1[5]=table2[month/10%10]; //月十位
  12.         table1[6]=table2[month%10];        //月个位
  13.         table1[8]=table2[day/10%10];        //日十位
  14.         table1[9]=table2[day%10];        //日个位
  15.         table1[14]=table2[week%10];        //星期个位
  16.                
  17.         lcd_write_cmd(0x80);//写命令,从第二行第1位开始
  18.         for(k=0;k<16;k++) //总共用了11个字符8位码+3位空
  19.         {
  20.                 lcd_write_dat(table1[k]);
  21.         }
  22.        
  23.                 time_num[0]=table2[shi/10%10]; //时十位
  24.                 time_num[1]=table2[shi%10];        //时个位       
  25.                 time_num[3]=table2[fen/10%10];        //分十位
  26.                 time_num[4]=table2[fen%10];        //分个位
  27.                 time_num[6]=table2[miao/10%10];        //秒十位
  28.                 time_num[7]=table2[miao%10];        //秒个位
  29.                 time_num[9]=table2[res/100%10];        //电压
  30.                 time_num[11]=table2[res/10%10];        //电压
  31.         time_num[12]=table2[res/1%10];        //电压

  32.                 lcd_write_cmd(0x90);//写命令,从第二行第1位开始
  33.                 for(j=0;j<14;j++) //总共用了11个字符8位码+3位空
  34.                 {
  35.                         lcd_write_dat(time_num[j]);
  36.                 }
  37. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 20:16 | 显示全部楼层
屏驱动
  1. //LCD12232
  2. //1->VSS 2->VCC 4->RS/CS 5->RW/SID 6->EN/SCLK
  3. //7-14 -> DB0-DB7 15->PSB 16->RST 17->BLA 5V 18->BLK 0V
  4. #include "SYSCFG.h"
  5. #include "delay.h"

  6. #define uchar unsigned char
  7. #define uint unsigned int

  8. #define lcd_cs PA5  //
  9. #define lcd_sid PA6  //
  10. #define lcd_sclk PA7  //

  11. //LCD12232串行方式
  12. void write_byte (uchar data1)  //发送一个字节
  13. {
  14.         uchar i;
  15.         for(i=0;i<8;i++)         //一个字节的8位
  16.         {
  17.                  lcd_sclk=1;           //先置高电平,准备读取数据
  18.                  if((data1 & 0x80)==0x80)
  19.         {lcd_sid=1; }
  20.         else
  21.         {lcd_sid=0;}//1000 0000左移i位再按位与2个1得1
  22.         delay_us(5);
  23.         lcd_sclk=0;           //下降沿数据变化
  24.         delay_us(5);
  25.                 data1<<=1;
  26.         
  27.         }
  28. }

  29. void lcd_write_cmd(uchar cmd)        //写命令
  30. {
  31.         delay_ms(10);
  32.     lcd_cs=1;        // 片选,高电平有效
  33.         write_byte(0xf8);   //第一字节 1111 1000 bit2 0表示从MCU到LCD bit1 0表示指令
  34.         write_byte(cmd & 0xf0);        //第二字节 1111 0000 按位与,传送高4位
  35.         write_byte((cmd<<4)&0xf0);        //第三字节 左移4位 传送低4位
  36.         lcd_cs=0;                //
  37. }

  38. void lcd_write_dat(uchar dat)        //写数据
  39. {
  40.         delay_ms(10);
  41.     lcd_cs=1;        //片选,高电平有效
  42.         write_byte(0xfa); //第一字节 1111 1010 bit2 0表示从MCU到LCD bit1 1表示数据
  43.         write_byte(dat & 0xf0);        //第二字节 1111 0000 按位与,传送高4位
  44.         write_byte((dat<<4)&0xf0);        //第三字节 左移4位 传送低4位
  45.         lcd_cs=0;       
  46. }

  47. void lcd_write_string(uchar *string)          //写字符串
  48. {
  49.         while (*string !='\0')        //直到字符串结尾才跳出循环
  50.         {
  51.                  lcd_write_dat(*string);          //把字符串写入
  52.                 string++;        //下一个
  53.         }
  54. }

  55. void lcd_init()
  56. {
  57. //        lcd_psb=0;        //1并行0串行
  58. //        lcd_rst=1;       
  59.         lcd_write_cmd(0x30);        //0011 0000基本指令8位
  60.         lcd_write_cmd(0x0c);        //0000 1100开显示,光标关
  61.         lcd_write_cmd(0x01);        //0000 0001清屏
  62. //        lcd_write_cmd(0x02);        //0000 0010清DDRAM
  63. //        lcd_write_cmd(0x06);        //0000 0110光标及显示右移一位
  64. //        lcd_write_cmd(0x0e);        //0000 1100开显示,光标开
  65. //        lcd_write_cmd(0x0f);        //0000 1111开显示,光标开,反白
  66. //        lcd_write_cmd(0x36);        //0011 0110扩展指令8位开绘图
  67. //        lcd_write_cmd(0x34);        //0011 0100扩展指令8位关绘图
  68. //        lcd_write_cmd(0x80);   //1000 0000第一行开始
  69. //        lcd_write_cmd(0x90);        //1001 0000第二行开始
  70. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 20:16 | 显示全部楼层
main部分
  1. // Project:  test.prj
  2. // Device:   FT61F023-RB SOP16
  3. // Memory:   PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte   
  4. // Description:
  5. // ADC通道2 PA2 检测电压,LCD12232时钟显示电压
  6. // RELEASE HISTORY
  7. // VERSION DATE     DESCRIPTION
  8. // 1.0   2025-4-30   首版

  9. #include "SYSCFG.h"   //
  10. #include "lcd12232.h"  //LCD驱动
  11. #include "display.h"  //显示
  12. #include "jishi.h"   //计时
  13. #include "ADC.h"  //ADC
  14. //#define uchar unsigned char 0-255
  15. //#define uint unsigned int 0-65536
  16. #define led PA4  //秒闪灯
  17. uint num; //定时器溢出次数,用于定时


  18. //上电系统初始化
  19. void POWER_INITIAL (void)
  20. {
  21.         OSCCON = 0B01110001;    //bit7 0->LIRC=32K 1->LIRC=256K
  22.                             //bit[6:4] 111->16MHz/2=8MHz,0.125us
  23.                                                     //bit0 0->外部 1->内部
  24.                                                     
  25.         INTCON = 0;                          //暂禁止所有中断               
  26.    
  27.         TRISA = 0B00000100;                //PA2输入 PA4 PA5 PA6 PA7 OUT                                                       
  28.         TRISC = 0B00000000;                //PC输入输出 0-输出 1-输入        
  29.     WPUA = 0B00000000;            //上拉
  30.     WPUC = 0B00000000;     //上拉
  31.     //WPDA = 0B00000000;    //下拉
  32.     //WPDC = 0B00000000;    //下拉
  33.            PORTA = 0B00000000;                //初值               
  34.         PORTC = 0B00000000;         //初值
  35.                                                                 
  36.         OPTION = 0B00000000;       
  37.                                                 //bit3->0=分配给TMR0
  38.                                                 //bit[2:0] PS->000=TMR0 Rate 1:2
  39.                              
  40.         MSCKCON = 0B00000000;
  41.                                                 //Bit6->0,禁止PA4,PC5稳压输出,PA4 PC5为普通IO
  42.                                                 //Bit5->0,TIMER2时钟为Fosc
  43.                                                 //Bit4->0,禁止LVR
  44.     CMCON0 = 0B00000111;
  45.                                                 //bit[2:0]->111关闭比较器,CxIN为数字IO口
  46. }

  47. //中断处理
  48. void interrupt ISR(void)
  49. {  
  50.         if(T0IE && T0IF)    //8.192ms翻转一次
  51.         {
  52.                 T0IF = 0;
  53.         num++;
  54.         if(num==122)  //8.192*122=1s
  55.         {
  56.                         num=0;  //归0
  57.             jishi();   //运行一次计时函数
  58.             led=~led;   //秒闪灯闪
  59.             ADC_convert(2);  //1秒采集一次数据
  60.         }
  61.         }
  62. }

  63. //设置TMR0定时时长=(1/系统时钟频率)*指令周期*预分频值*255
  64. //                                   =(1/16000000)*2*256*255=8.192ms
  65. void timer0_initial (void)  
  66. {
  67.         OPTION = 0B00000111;
  68.                         //Bit5                T0CS Timer0时钟源选择
  69.                         //                        1-外部引脚电平变化T0CKI 0-内部时钟(FOSC/2)
  70.                         //Bit4                T0CKI引脚触发方式 1-下降沿 0-上升沿
  71.                         //Bit3                PSA 预分频器分配位 0->Timer0 1->WDT
  72.                         //Bit[2:0]        PS 8个预分频比 111->1:256
  73.         T0IF = 0;                                //清空T0软件中断
  74.     T0IE=1;  //开定时器0中断
  75. }



  76. //主函数
  77. void main()
  78. {
  79.         POWER_INITIAL();   //上电初始化
  80.     timer0_initial();  //定时器初始化
  81.     ADC_INITIAL();           //ADC初始化       
  82.     GIE=1;  //开中断
  83.    
  84.     lcd_init();        //LCD12232初始化  
  85.         while(1)
  86.         {
  87.                 lcd_display();  //显示
  88.        
  89.         }
  90. }
  91. //end
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 20:19 | 显示全部楼层
所有 代码都在这个文件夹内


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 昨天 22:21 来自手机浏览器 | 显示全部楼层
这个时钟能调时吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 22:27 | 显示全部楼层
触景情伤 发表于 2025-4-30 22:21
这个时钟能调时吗?

这个我没设计按键,
加几个铵键是很简单的事情,
回复 支持 反对

使用道具 举报

发表于 昨天 23:08 来自手机浏览器 | 显示全部楼层
hellozwt 发表于 2025-4-30 22:27
这个我没设计按键,
加几个铵键是很简单的事情,

没有时钟RTC模块还可以,一旦有RTC模块我就不会写按键了…
回复 支持 反对

使用道具 举报

发表于 5 小时前 | 显示全部楼层
谢谢分享支持一下!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-1 14:25 , Processed in 0.202800 second(s), 10 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表