资讯详情

一个简单的单片机直流可调稳压电源设计

通过做可以掌握A/D,D/A模块的使用,51单片机程序分为处理、D/A、A/D和存储四个模块。运用扫描法,对键盘进行扫描,有按键就更改输入TLC5615 的数值,ADD按键是对数据进行加以操做,长按的话使步进值增大,实现快加,SUB按键与ADD按键同,预读取按键用于读取 AT24C04 中预置的数值,保存按键用于保存当前电压值;显示部分主要是对TLC549采集回来的电压进行处理显示,它主要是在定时器0的中断服务程序中显示,100ms刷新显示一次;TLC5615 模块,通过对dA的串行数据输入,使其在输出电压时可控,输出电压后经lm324,三极管,加上负载输出电压,输出电压后,用TLC549芯片100ms采集一次,送显示。 完整的工程文件及hex文件下载地址:http://www.51hei.com/f/dpjdianyuan_c.rar

AT24C04.h 代码

sbit LK=P1^6; sbit SDA=P1^7; sbit a7=ACC^7; sbit a6=ACC^6; sbit a5=ACC^5; sbit a4=ACC^4; sbit a3=ACC^3; sbit a2=ACC^2; sbit a1=ACC^1; sbit a0=ACC^0; /********************* *******24C04的初始化** **** **************/ void init_24C04() { SDA=1; _nop_(); ATCLK=1; _nop_(); } /********************* ****启动24C04********* *******************/ void start_24C04() {

SDA=1; _nop_(); ATCLK=1; _nop_();

SDA=0; _nop_(); ATCLK=0; _nop_(); } /******************** *****停止24C04******* *********************/ void stop_24C04() { SDA=0; _nop_();

ATCLK=1; _nop_(); SDA=1; _nop_();

} /********************* ****24C04应答********* *******************/ void response() { unsigned char i; ATCLK=1; _nop_(); while((SDA==1)&&(i<250))i++; ATCLK=0; _nop_(); } /******************** *****读取24C04一个字节** **************************/ unsigned char read_byte() { SDA=1; ATCLK=1;a7=SDA;ATCLK=0; ATCLK=1;a6=SDA;ATCLK=0; ATCLK=1;a5=SDA;ATCLK=0; ATCLK=1;a4=SDA;ATCLK=0; ATCLK=1;a3=SDA;ATCLK=0; ATCLK=1;a2=SDA;ATCLK=0; ATCLK=1;a1=SDA;ATCLK=0; ATCLK=1;a0=SDA;ATCLK=0; SDA=1; ATCLK=0; return ACC; } /************************* **写入24C04一个字节****** *************************/ void write_byte(unsigned char addr) { ACC=addr; SDA=a7;ATCLK=1;ATCLK=0; SDA=a6;ATCLK=1;ATCLK=0; SDA=a5;ATCLK=1;ATCLK=0; SDA=a4;ATCLK=1;ATCLK=0; SDA=a3;ATCLK=1;ATCLK=0; SDA=a2;ATCLK=1;ATCLK=0; SDA=a1;ATCLK=1;ATCLK=0; SDA=a0;ATCLK=1;ATCLK=0; SDA=1; ATCLK=0;

} /*********************** **写24C04的数据******* *****************/ void write_24C04(unsigned char addr,unsigned char dat) { start_24C04(); write_byte(0xa0); response(); write_byte(addr); response(); write_byte(dat); response(); stop_24C04(); } /********************** ***读24C04的数据******* *****************/ unsigned char read_24C04(unsigned char addr) { unsigned char t; start_24C04(); write_byte(0xa0); response(); write_byte(addr); response(); start_24C04(); write_byte(0xa1); response(); t=read_byte(); stop_24C04(); return t; }

main.c 代码 #include"reg52.h" #include "intrins.h" #include "AT24C04.h"

#define uchar unsigned char #define uint unsigned int

uchar code LED[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; uchar code Bit_sel[4] = {0x08,0x04,0x02,0x01 }; //各个数码管对应的位选数据

sbit DIO = P1^0; //数据线 sbit CS = P1^1; //片选 sbit CLK = P1^2; //io口时钟

sbit = P1^4; sbit SDATA = P1^5; sbit SCLK = P1^3;

sbit ADD = P3^0; sbit SUB = P3^1; sbit Pre_read = P3^2; sbit Store = P3^3;

uint qian,bai,shi,ge; //用于显示数码管的 千,百,十,个 等四位的显示 uint val,num; //val 是用于输入DA 的数据,num是用于判断是不是长按的 uint cp; //计数的变量 uchar key_stat; uchar add_stat,sub_stat; uchar st_flag,pre_flag;

void delay(uint x) //微妙级是延时函数 { while(x--) _nop_(); }

/********************************************** 函数名称:deal 函数作用:处理AD的返回值 函数参数:无 函数返回值:无 **********************************************/ void deal(uint num) //显示程序 { qian=num/1000; //千,百,十,个处理 bai=num/100%10; shi=num/10%10; ge=num%10; }

/********************************************** 函数名称:TL549_AD() 函数作用:返回AD的返回值 函数参数:无 函数返回值:data_ad **********************************************/ uint TL549_AD() //TLC549处理 { uchar i; uint data_ad = 0; CS = 1; //初始化,启动 CLK = 0; CS = 0; _nop_(); for(i = 0;i < 8;i++) //读取采集数据,读取的是上一次采集数据 { CLK = 1; if(DIO)data_ad |= 0x01; CLK = 0; data_ad = data_ad << 1; } CS = 1; data_ad = data_ad * (500/ 256); return(data_ad); }

/********************************************** 函数名称:TLC5615_DA(uint da) 函数作用:TLC5615_DA 将da转换后模拟输出 函数参数:da 函数返回值:无 **********************************************/ void TLC5615_DA(uint da) // TLC5615 的DA 转换函数 { uchar i; da<<=6;

SCS=0; SCLK=0;

for (i=0;i<12;i++) { SDATA=(bit)(da&0x8000); SCLK=1; da<<=1; SCLK=0; }

SCS=1; SCLK=0; for (i=0;i<12;i++); } /********************************************** 函数名称:key_scan() 函数作用:处理那些独立键盘 函数参数:无 函数返回值:无 **********************************************/ void key_scan() { if (ADD == 0) // ADD 按键的键盘处理函数 { delay(10); if (ADD == 0) { add_stat = 1; num ++; } else { add_stat = 0; num = 0; } //此处判断是不是长按,长按的话 使其步进值 加大 if (ADD == 0 && add_stat == 1 && num >= 300) { val += 5; num = 0; } if (ADD == 1 && add_stat == 1) { val ++; num = 0; add_stat = 0; } if (val >= 1024) { val = 1023; } }

if (SUB == 0) //SUB 按键的键盘处理函数 { delay(10); if (SUB == 0) { sub_stat = 1; num ++; } if (SUB == 0 && sub_stat == 1 && num >= 300) { val -= 5; num = 0; } if (SUB == 1 && sub_stat == 1) { val --; num = 0; sub_stat = 0; } if (val <= 0) val = 0; }

if (Pre_read == 0) //预读数据的 键盘处理函数 { delay(100); if (Pre_read == 0) { pre_flag = 1; } if (Pre_read == 1 &&pre_flag == 1 ) { pre_flag = 0; val = read_24C04(20); //从AT24C04中的地址20 中读出预存储的数据 } }

if (Store == 0) //保存数值 按键的键盘处理函数 { delay(100); if (Store == 0) { st_flag = 1; } if (Store == 1 && st_flag == 1) { st_flag = 0; write_24C04(20,val); //向AT24C04中的地址20 写入存储的数据 } } } /********************************************** 函数名称:timer0_init (void) 函数作用:初始化定时器0,并设置 函数参数:无 函数返回值:无 **********************************************/ void timer0_init (void) // timer0中断初始化函数 { EA = 0; TMOD = 0x01; TR0 = 0; TL0 = (65536-5000)%256; //设置初值 TH0 = (65536-5000)/256; PT0 = 1; ET0 = 1; EA = 1; TR0 = 1; } /********************************************** 函数名称:main(void) 函数作用:main主函数入口 函数参数:无 函数返回值:无 **********************************************/ void main(void) //主程序 { timer0_init(); //初始化定时器0 init_24C04(); //初始化AT24C04 while(1) { key_scan(); //调用键盘扫描函数 TLC5615_DA(val); //处理键盘发送过来的值 } }

/********************************************** 函数名称:timer0_isr(void) interrupt 1 函数作用:定时器0,方式1,的中断服务子程序 函数参数:无 函数返回值:无<

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台