蓝桥杯单片机 | 特训案例【进阶06】基于PCF8591的DAC模拟电压输出

/*==================蓝桥杯单片机特训==================【进阶06】:基于PCF8591的DAC模拟电压输出**平 台:CT107D单片机综合实训平台**模 式:IO模式**底层驱动文件:2022年竞赛资源数据包提供的文件**设 计:欧浩源(小蜜蜂老师,ohy3686@qq.com)**时 间:2022-04-05**更多详见:www.xmf393.com====================================================*/#include "reg52.h"#include "iic.h"sbit S4 = P3^3;//定义动态显示中单个数码管点亮时长#define TSMG 500//-------共阳数码管的段码编码表(无小数点)--------//0 1 2 3 4 5 6 7 8 9 A B C D E F - .unsigned char code SMG_NoDot[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};//-------共阳数码管的段码编码表(带小数点)--------//0. 1. 2. 3. 4. 5. 6. 7. 8. 9.unsigned char code SMG_Dot[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//-----------------------------------------------unsigned char adc_value = 0; //AIN3的采样数据float adc_volt = 0; //AIN3的换算电压unsigned int smg_volt = 0; //AIN3的显示电压unsigned char stat_smg = 1; //当前显示界面标志unsigned char mode = 1; //模式//==============数码管动态显示专用延时函数=============void DelaySMG(unsigned int t){while(t--);}//==================设置选通的锁存器===================void Set_HC573(unsigned char channel, unsigned char dat){P0 = dat; //待设置数据switch(channel) //选通锁存器{case 4:P2 = (P2 & 0x1f) | 0x80; //Y4输出0,LED控制break;case 5:P2 = (P2 & 0x1f) | 0xa0; //Y5输出0,蜂鸣器和继电器控制break;case 6:P2 = (P2 & 0x1f) | 0xc0; //Y6输出0,数码管位选break;case 7:P2 = (P2 & 0x1f) | 0xe0; //Y7输出0,数码管段码break;case 0:P2 = (P2 & 0x1f) | 0x00; //所有锁存器不选择break;}P2 = (P2 & 0x1f) | 0x00; //设置完成,关闭全部锁存器}//=================单个数码管动态显示=================void DisplaySMG_Bit(unsigned char pos, unsigned char value){Set_HC573(6, 0x01 << pos); //数码管的段位Set_HC573(7, value); //数码管显示内容DelaySMG(TSMG); //数码管点亮时长Set_HC573(6, 0x01 << pos);Set_HC573(7, 0xff); //消隐}//=================全部数码管静态显示=================void DisplaySMG_All(unsigned char value){Set_HC573(6, 0xff); //使能所有数码管Set_HC573(7, value); //数码管显示内容}//===================电压值显示函数===================void DisplaySMG_ADC(){//输出电压DisplaySMG_Bit(7,SMG_NoDot[smg_volt % 10]);DisplaySMG_Bit(6,SMG_NoDot[(smg_volt / 10) % 10]);DisplaySMG_Bit(5,SMG_Dot[smg_volt / 100]);//工作模式DisplaySMG_Bit(2,SMG_NoDot[16]);DisplaySMG_Bit(1,SMG_NoDot[mode]);DisplaySMG_Bit(0,SMG_NoDot[16]);}//===============PCF8591电压采样处理函数===============void Read_PCF8591_AIN3(){IIC_Start();IIC_SendByte(0x90); //PCF8591的写设备地址IIC_WaitAck();IIC_SendByte(0x43); //输出DAC,转换AIN3IIC_WaitAck();IIC_Stop();DisplaySMG_ADC(); //等待电压转换完成IIC_Start();IIC_SendByte(0x91); //PCF8591的读设备地址IIC_WaitAck();adc_value = IIC_RecByte(); //读出AD采样数据IIC_SendAck(1); //产生非应答信号IIC_Stop();//将ADC采样到的数据换算成对应的电压值adc_volt = adc_value * (5.0 / 255);smg_volt = adc_volt * 100;}//===============PCF8591电压输出设置函数===============void Set_PCF8591_DAC(unsigned char dat){IIC_Start();IIC_SendByte(0x90); //PCF8591的写设备地址IIC_WaitAck();IIC_SendByte(0x43); //输出DAC,转换AIN3IIC_WaitAck();IIC_SendByte(dat); //设置DAC电压输出参数IIC_WaitAck(); //产生非应答信号IIC_Stop();}//===================按键扫描处理函数==================void Scan_Keys(){if(S4 == 0){DelaySMG(500);if(S4 == 0){if(mode == 1){mode = 2; //切换为模式2Set_PCF8591_DAC(204); //输出固定电压4Vsmg_volt = 400; //显示电压:4.00}else if(mode == 2){mode = 3; //切换为模式3}else if(mode == 3){mode = 1; //切换为模式1Set_PCF8591_DAC(102); //输出固定电压2Vsmg_volt = 200; //显示电压:2.00}while(S4 == 0) //松手检测{DisplaySMG_ADC(); //保持数码管动态显示}}}}//=====================系统初始化=====================void Init_sys(){Set_HC573(0, 0x00); //关闭所有锁存器Set_HC573(5, 0x00); //关闭蜂鸣器和继电器Set_HC573(4, 0xff); //关闭全部LED灯DisplaySMG_All(0xff); //关闭全部数码管Set_PCF8591_DAC(102); //输出固定电压2Vsmg_volt = 200; //数码管显示2.00V}//=======================主函数=======================void main(){Init_sys(); //系统初始化while(1){if(mode == 3) //模式3:可调电阻控制DAC输出{Read_PCF8591_AIN3(); //采样AIN3电压Set_PCF8591_DAC(adc_value); //更新DAC输出参数}Scan_Keys(); //循环扫描按键DisplaySMG_ADC(); //动态刷新数码管}}//========================END==========================

添加 家长论坛微信

全部 0条评论