📄 mega128_232.c
字号:
/*******************************************/
/* 项目试验AD转换电阻_电压调整等程序 */
/* 2007年7月6日 */
/* 目标MCU:MEGA128/64 晶振:外部 11.0592/(8MHZ) */
/*******************************************/
#include <iom64v.h>
//#include <iom128v.h>
#include <macros.h>
#define Vref 1000 //参考电压值
void xianshi(void);
extern unsigned int wen_ding[32]={0,0,0,0,0,0,0,0,0,0};
extern unsigned int ADC_jieguo[32]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
extern unsigned char led_buff[4]={0,0,0,0}; ////
extern unsigned char lleedd_buff[4]={0,0,0,0};
extern unsigned char dianya_hui[10]={0,0,0,0,0,0,0,0,0,0};
extern unsigned char dianya_mingling[7]={0x05,0x00,0x52,0xb6,0x03,0xe2,0x03};
extern const unsigned char BCD[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};////0123456789A
extern void delay_ms(unsigned int time);
extern void delay_us(unsigned char time);
extern void display(void);
extern void tongxun_dianya(void);
extern void tongxun_diannao(void);
extern void tongxun_diannao2(void);
unsigned int bao_cun; //电阻初测保存2倍值
//unsigned int adc_rel ;//AD转换结果
//unsigned char adc_mux;//AD通道
//ADC初始化
void adc_init(void)
{
DDRF=0x00;
PORTF=0x00;
ADCSRA=0x00;
ADMUX =0x00;////外部1v基准,通道0//
ACSR =(1<<ACD);//关闭模拟比较器
ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1) ;//64分频并启动一次转换
}
void delay_us(unsigned char time) //*微秒级延时程序*//
{ do
{ time--; }
while (time>1);
}
void delay_ms(unsigned int time) //*毫秒级延时程序*//
{ while(time!=0)
{ delay_us(0xff);
xianshi();
time--; }
}
////显示程序//////////
void xianshi(void)
{ ///////初测保存显示//////
PORTA=BCD[led_buff[0]];
PORTC=0xef; ///千位数 ///BIT/5
delay_us(0xa0);
PORTA=BCD[led_buff[1]];
PORTC=0xdf; ///百位数 ///BIT/6
delay_us(0xa0);
PORTA=BCD[led_buff[2]];
PORTC=0xbf; ///十位数 ///BIT/7
delay_us(0xa0);
PORTA=BCD[led_buff[3]];
PORTC=0x7f; ///个位数 ///BIT/8
delay_us(0xa0);
PORTA=0x7f; /////BIT/x点小数点
PORTC=0xbf; /////BIT/6点小数点
delay_us(0xa0);
/////2倍显示////////
PORTA=BCD[lleedd_buff[0]];
PORTC=0xfe; ///千位数 ///BIT/1
delay_us(0xa0);
PORTA=BCD[lleedd_buff[1]];
PORTC=0xfd; ///百位数 ///BIT/2
delay_us(0xa0);
PORTA=BCD[lleedd_buff[2]];
PORTC=0xfb; ///十位数 ///BIT/3
delay_us(0xa0);
PORTA=BCD[lleedd_buff[3]];
PORTC=0xf7; ///个位数 ///BIT/4
delay_us(0xa0);
PORTA=0x7f; /////BIT/x点小数点
PORTC=0xfb; /////BIT/1点小数点
delay_us(0xa0);
}
///////AD数据处理程序///////
void shuju_chuli(void)
{ unsigned char m,n;
for(n=0;n<32;n++)
{ for(m=0;m<32;m++)
{ while(ADIF==0) //等待中断标志
{ NOP(); }
ADC_jieguo[m]=ADC&0x3ff; //读结果
ADCSRA|=(1<<ADIF); //清中断
ADCSRA|=(1<<ADSC); //启动AD转换
}
xianshi(); //刷新显示
for(m=0;m<31;m++)
{ ADC_jieguo[0]=ADC_jieguo[0]+ADC_jieguo[m+1];}
wen_ding[n]=ADC_jieguo[0]>>5;
}
for(n=0;n<31;n++)
{wen_ding[0]=wen_ding[0]+wen_ding[n+1];}
wen_ding[0]=wen_ding[0]>>5;
}
////////十进制数据处理程序///数组数据作指针指向十进制字符数组////
void shijinzhi_chuli(void)
{ unsigned int v;
unsigned char m;
v=wen_ding[0]; //取数据进行十进制转换
for(m=4;m>0;m--)
{ lleedd_buff[m-1]=v%0x0a; ///十进制数首先送进2倍数组
v=wen_ding[0];
v=v/0x0a;
wen_ding[0]=v;
}
}
//////*电阻测量保存程序**********////////
void dian_zu(void)
{
//unsigned int v;
unsigned char i;
PORTE&=~(1<<PORTE7); ///关指示灯
ADMUX =0;///////外部1v基准,通道0//
ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1) ;//64分频
PORTB=0xff; //关闭输出
while(PIND&(1<<PD6)) ////在测量保存电阻状态下等待启动
{xianshi();} //刷新显示
delay_ms(0x1ff); ///等待电路稳定
PORTB&=~(1<<PORTB0); ////KM1转换成测电阻回路
delay_ms(0x3ff); ///等待电路稳定
PORTB&=~(1<<PORTB1); ////输出10mA电流
delay_ms(0x3ff); ///等待电路稳定
for(i=0x10;i>0;i--)
{
shuju_chuli(); ////数据处理程序,里面包涵刷新显示程序
bao_cun=wen_ding[0]; //电阻初测保存值
bao_cun=bao_cun<<1; //电阻初测保存值的2倍
shijinzhi_chuli(); //十进制数据处理程序
}
for(i=0;i<4;i++)
{
led_buff[i]=lleedd_buff[i]; ////再从二倍数组取出数据送入常温电阻
}
xianshi(); //刷新显示
PORTB=0xff; //关一次B口
PORTE|=(1<<PORTE7); ////峰鸣声音提示
}
//////*恢复时间和电阻比较程序**********////////
void dianzu_bijiao(void)
{
unsigned int k;
unsigned char i;
PORTE&=~(1<<PORTE7); ///关指示灯
delay_ms(0x0f); ///延时等待电路稳定 里面包涵刷新显示程序
ADMUX =0; ///////外部1v基准,通道0//
ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1) ;//64分频
PORTB=0xff; //关一次B口
delay_ms(0x20);
tongxun_dianya(); ////通讯读电压值并处理显示
k=wen_ding[0]; //取数据
while((k>282)|(k<278)) ////从280V开始
{
if(k<270) ////和270.0V比较
{
PORTB|=(1<<PORTB3); ////正转控制
delay_ms(0x20);
PORTB&=~(1<<PORTB4); ///升压
delay_ms(0x50); ///转动时间 修改成5V每秒
PORTB|=(1<<PORTB4); ///升压停止
delay_ms(0x50); ///转动间隔 修改成5V每秒
}
if(k<278) ///小于278V
{
PORTB|=(1<<PORTB3); ////正转控制
delay_ms(0x20);
PORTB&=~(1<<PORTB4); ///升压
delay_ms(0x30); ///修改成1V每秒
PORTB|=(1<<PORTB4); ///升压停止
delay_ms(0x60); ///转动间隔 修改成1V每秒
}
if(k>288) ///比288.0V高
{
PORTB&=~(1<<PORTB3); ////反转控制
delay_ms(0x20);
PORTB&=~(1<<PORTB4); ///降压
delay_ms(0x50); ///向下微调
PORTB|=(1<<PORTB4); ///降压停止
delay_ms(0x50); ///转动间隔 修改成5V每秒
}
if(k>282) ///比282.V高
{
PORTB&=~(1<<PORTB3); ////反转控制
delay_ms(0x20);
PORTB&=~(1<<PORTB4); ///降压
delay_ms(0x30); ///向下微调
PORTB|=(1<<PORTB4); ///降压停止
delay_ms(0x50); ///转动间隔 修改成1V每秒
}
delay_ms(0xff);
tongxun_dianya(); ////通讯读电压值并处理显示
k=wen_ding[0]; //取数据
}
delay_ms(0x4ff);
if(PING==0x19)
{PORTB&=~(1<<PORTB2);
PORTB&=~(1<<PORTB5);
} ////KM2接通主电流回路并启动10分钟计时
delay_ms(0x6ff);
while(PIND&(1<<PIND4)) ////等待10分钟满
{
if(k<278) ///小于278V
{
PORTB|=(1<<PORTB3); ////正转控制
delay_ms(0x20);
PORTB&=~(1<<PORTB4); ///升压
delay_ms(0x20); ///修改成1V每秒
PORTB|=(1<<PORTB4); ///升压停止
delay_ms(0x80); ///转动间隔 修改成1V每秒
}
else if(k>282) ///比282.V高
{
PORTB&=~(1<<PORTB3); ////反转控制
delay_ms(0x20);
PORTB&=~(1<<PORTB4); ///降压
delay_ms(0x20); ///向下微调
PORTB|=(1<<PORTB4); ///降压停止
delay_ms(0x80); ///转动间隔 修改成1V每秒
}
delay_ms(0xfff);
tongxun_dianya(); ////通讯读电压值并处理显示
k=wen_ding[0]; //取数据
}
PORTB|=(1<<PORTB2); ////KM2断开主电流回路
if(PING==0x19)
{PORTB&=~(1<<PORTB6);} ////启动3分钟计时
delay_ms(0x1fff); ///长延时等待电路稳定1fff大约7秒
if(PING==0x19)
{
PORTB&=~(1<<PORTB0); ////KM1转换成测电阻回路PORTB&=~(1<<PORTB0); ////KM1转换成测电阻回路
}
if(PING==0x19)
{
delay_ms(0xaff); ///等待电路稳定
PORTB&=~(1<<PORTB1); ////输出10mA电流
delay_ms(0x5ff); ///等待电路稳定
}
if(PING==0x19)
{
shuju_chuli(); ////AD数据处理程序,里面包涵刷新显示程序
shijinzhi_chuli(); ////十进制处理
shuju_chuli(); ////在转换一次AD,取出比较用的电阻值wen_ding[0]
}
while(wen_ding[0]>bao_cun) //和保存的二倍值比较
{
shuju_chuli(); ////AD数据处理程序,里面包涵刷新显示程序
shijinzhi_chuli(); ////十进制处理
shuju_chuli(); ////在转换一次AD,取出比较用的电阻值wen_ding[0]
if(PING!=0x19)
break;
}
xianshi(); //刷新显示
PORTB&=~(1<<PORTB7); //小于保存的二倍值暂停恢复计时
shijinzhi_chuli(); //十进制数据处理程序
for(i=0;i<3;i++)
{ PORTE&=~(1<<PORTE7); ////峰鸣声音提示
delay_ms(0xaf); ////峰鸣声音延时
PORTE|=(1<<PORTE7);
delay_ms(0xaf); ////峰鸣声音延时
}
}
/////////通讯电压测量读取显示//////9600,n,8,1/////////
void tongxun_dianya(void)
{
unsigned int k;
unsigned char i;
UBRR0H=0;
UBRR0L=71; /// UBRR(波特率9600)
UCSR0C=0x06; //无校验1位停止位8数据位
UCSR0B=(1<<RXEN0)|(1<<TXEN0); //允许发送和接收
xianshi(); //刷新显示
PORTE|=(1<<PORTE2); ////使能485发送DE置位发送使能
for(i=0;i<7;i++)
{ while(!(UCSR0A&(1<<UDRE0))) //置usart数据寄存器空,系统复位时,udre位置1,表示数据发送已准备好
{NOP();}
UDR0=dianya_mingling[i];//数据寄存器 循环发送数据读电压值命令
NOP();
while(!(UCSR0A&(1<<TXC0)))
{NOP();}
UCSR0A|=(1<<TXC0);
}
PORTE&=~(1<<PORTE2); ////使能485接收RE置位接收使能
NOP();
TCCR0=0x07;
TCNT0=0xaa;
for(i=0;i<10;i++)
{
while(!(UCSR0A&(1<<RXC0)));//将第七位RXC置1,表示USART接受完成
{
if(TOV0==1)
{break;}
NOP();
}
dianya_hui[i]=UDR0;//数据寄存器udr0循环接收数据(读电压值)
NOP();
}
TCCR0=0x00;
TIFR|=(1<<TOV0);
PORTE|=(1<<PORTE2); ////使能485发送DE置位发送使能
delay_ms(0x0f);
if(dianya_hui[9]==0x03)
{
dianya_hui[7]&=0x7f; //屏蔽符号位变成正数
if(dianya_hui[7]>0x40)
{dianya_hui[7]-=0x40;}
else{dianya_hui[7]=0;}
k=(dianya_hui[6]<<8)|dianya_hui[5];
k=k>>(16-dianya_hui[7]); ///移位取整数
wen_ding[0]=(k<<3)+(k<<1); ///乘10让开小数点
shijinzhi_chuli(); ////十进制显示处理
wen_ding[0]=k; ////恢复wen_ding[0]的值以便调用它的程序使用
}
}
///////////耗散功率下限调压后28零0V稳压//
void xiaxian_tiaoya(void)
{
unsigned int k;
//unsigned char i;
PORTB=0xff;//关一次B口
PORTE&=~(1<<PORTE7); ///关指示灯
delay_ms(0x10); ///等待电路稳定内含刷新显示
while(PIND&(1<<PIND0)) ////等待调压器下限复位
{
PORTB&=~(1<<PORTB3); ////KM5切换到反转
PORTB&=~(1<<PORTB4); ////此时反旋转输出
xianshi(); //刷新显示
}
delay_ms(0xff);
PORTB|=(1<<PORTB4); ////停止转动
PORTB&=~(1<<PORTB2); ////KM2接通主电流回路
PORTB&=~(1<<PORTB5); ////启动10分钟计时
xianshi(); //刷新显示
while(PIND&(1<<PIND4)) ////等待10分钟计时满
{
if(k<268) ////和275.0V比较
{
PORTB|=(1<<PORTB3); ////正转控制
delay_ms(0x20);
PORTB&=~(1<<PORTB4); ///升压 此时正旋转输出
delay_ms(0x2d); ///转动时间 修改成5V每秒
PORTB|=(1<<PORTB4); ///升压停止
delay_ms(0x80); ///转动间隔 修改成5V每秒
}
if(k<278) ///大于275.0V小于279.0V
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -