数控步进直流稳压电源(c程序)
时间:12-15 11:47 阅读:2989次
*温馨提示:点击图片可以放大观看高清大图
简介:本文主要介绍的是利用c语言数控步进直流稳压电源程序设计。
#i nclude
//此程序实现"数控步进直流稳压电源"的功能,调试时为了避免资源冲突,应使实验板上 的拔码开
关S8拔向高电平
//本程序设定S9键为增加键,当按住S9键不松开时,输出Vout以0.1V连续步进,
//直至键S9松开,当以一定的时间间隔点动S9键时,输出Vout也为点动步进
//递减键S11的功能与S9基本相同时,输出电压的值显示在3个LED上
unsigned char R1,R2,R3,TXDATA,LEDF,BJF,COUNTW,data;
unsigned int i;
const char table[11]={0xc0,0xf9,0xa4,0xb0,0x99, 0x92, 0x82
,0XD8,0x80,0x90,0xFF};
//不带小数点的显示段码表
const char table0[11]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10,
0xFF};
//带小数点的的显示段码表
unsigned char s[4]; //定义一个显示缓冲数组
//把需要显示的数字装入显示缓冲数组
void sfz()
{
s[0]=R3;
s[1]=R2;
s[2]=R1;
s[3]=0x0A; //最后一个LED显示"DARK"
}
//系统各寄存器初始化子程序
void initial()
{
R1=0X00;
R2=0X00;
R3=0X00;
sfz(); //把需要显示的数字装入显示缓冲数组
TXDATA=0X00;
LEDF=0X01;
BJF=0X01;
TRISB1=0;
TRISB2=0;
TRISB4=1;
TRISB5=1; //设置与键盘相关的各口的输入输出方式
RB1=0;
RB2=0; //设置扫描初始条件
}
//spi方式显示初始化子程序
void SPIINIT()
{
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
//设置SPI的控制方式,允许SSP方式,并且时钟下降沿发送,与"74HC595,当其
//SCLK从低到高跳变时,串行输入寄存器"的特点相对应
TRISC=0xD7; //SDO引脚为输出,SCK引脚为输出
TRISA5=0; //RA5引脚设置为输出,以输出显示锁存信号
}
//I2C初始化子程序
void i2cint()
{
SSPCON = 0X08; //初始化SSPCON寄存器
TRISC3 =1; //设置SCL为输入口
TRISC4 =1; //设置SDA为输入口
TRISA4 = 0;
SSPSTAT=0X80; //初始化SSPSTAT寄存器
SSPADD=0X02; //设定I2C时钟频率
SSPCON2=0X00; //初始化SSPCON2寄存器
di(); //关闭总中断
SSPIF=0; //清SSP中断标志
RA4=0; //关掉74HC165的移位时钟使能,以免74HC165
//移位数据输出与I2C总线的数据线发生冲突
SSPEN=1; //SSP模块使能
}
//软件延时子程序
void DELAY()
{
for(i = 3553; --i ;) continue;
}
//键服务子程序
void keyserve()
{
PORTB=0XFD ;
if(RB5==0) BJF=0X01; //S9键按下,步进加标志置1
PORTB=0XFB ;
if(RB5==0) BJF=0X00; //S11键按下,步进加标志清0
RB1=0; //恢复PORTB的值
RB2=0;
}
//键扫描子程序
void KEYSCAN()
{
while(1){
while(1) {
if (RB5==0) break;
}
DELAY(); //若有键按下,则软件延时
if (RB5==0)break; //若还有键按下,则终止循环扫描,返回
}
}
//SPI传送数据子程序
void SPILED(data)
{
SSPBUF=data; // 启动发送
do {
;
}while(SSPIF==0);
SSPIF=0;
}
//显示子程序
void display()
{
SPIINIT(); //spi方式显示初始化
RA5=0; //准备锁存
for(COUNTW=0;COUNTW<4;COUNTW++) {
data=s[COUNTW];
if(COUNTW==1) data=table0[data];//第二位需要显示小数点
else data=table[data];
SPILED(data); //发送显示段码
}
for(COUNTW=0;COUNTW<4;COUNTW++){
data=0xFF;
SPILED(data); //连续发送4个DARK,使显示看起来好看一些
}
RA5=1; //最后给一个锁存信号,代表显示任务完成
}
//I2C总线输出数据子程序
void i2cout()
{
i2cint(); //因为SPI输出和I2C输出不能同时工作,则需要
//不断在两种方式见切换
SEN=1; //产生I2C启动信号
for(i=0x02;--i;) continue; //给予一定的延时,保证启动
do {
RSEN=1; //产生I2C启动信号
}while(SSPIF==0); //如果没能启动,则反复启动,直到启动为止
SSPIF=0; //SSPIF标志清0
SSPBUF=0X58; //I2C总线发送地址字节
do {
;
}while(SSPIF==0); //等待地址发送完毕
SSPIF=0; //SSPIF标志清0
SSPBUF=0X01; //I2C总线发送命令字节
do {
;
}while(SSPIF==0); //等待命令发送完毕
SSPIF=0; //SSPIF标志清0
SSPBUF=TXDATA; //I2C总线发送数据字节
do {
;
}while(SSPIF==0); //等待数据发送完毕
SSPIF=0; //SSPIF标志清0
PEN=1; //产生停止条件
do {
;
}while(SSPIF==0); //等待停止条件产生
SSPIF=0; //SSPIF标志清0
}
//步进加子程序
void BJADD()
{
R1++;
TXDATA=TXDATA+2;
if(R1>9) {
R1=0;
R2++;
if(R2>9) {
R2=0;
R3++;
}
}
if((R3==1)&&(R2==2)&&(R1==1)){
R3=0;
R2=0;
R1=0; //若R3,R2,R1超过120,则又从0计起
TXDATA=0;
}
sfz(); //把需要显示的数字装入显示缓冲数组
}
//步进减子程序
void BJSUB()
{
R1--;
TXDATA=TXDATA-2;
if(R1==0XFF) {
R1=9;
R2--;
if(R2==0XFF) {
R2=9;
R3--;
if(R3==0XFF) {
R3=1;
R2=2;
R1=0;//若R3,R2,R1小于0,则又从120计起
TXDATA=0XF0;
}
}
}
sfz(); //把需要显示的数字装入显示缓冲数组
}
//主程序
main()
{
initial(); //系统各寄存器初始化
display(); //调用一次显示子程序
while(1) {
i2cout(); //调用I2C子程序,启动D/A转换
KEYSCAN(); //键盘扫描
keyserve() ; //若确实有键按下,则调用键服务程序
if(BJF==0X01) BJADD();//若步进加标志为1,则调用步进加子程序
else BJSUB(); //若步进加标志为0,则调用步进减子程序
display(); //调用一次显示子程序
}