?? 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 + -