?? main.c
字號:
/*eeprom_is_ready() //EEPROM 忙檢測(返回EEWE 位)
eeprom_busy_wait() //查詢等待EEPROM 準備就緒
uint8_t eeprom_read_byte (const uint8_t *addr) //從指定地址讀一字節(jié)
uint16_t eeprom_read_word (const uint16_t *addr) //從指定地址一字
void eeprom_read_block (void *buf, const void *addr, size_t n) //讀塊
void eeprom_write_byte (uint8_t *addr, uint8_t val) //寫一字節(jié)至指定地址
void eeprom_write_word (uint16_t *addr, uint16_t val) //寫一字到指定地址
void eeprom_write_block (const void *buf, void *addr, size_t n)//寫塊*/
/*
SIG_INTERRUPT0 外部中斷INT0
SIG_INTERRUPT1 外部中斷INT1
SIG_OUTPUT_COMPARE2 定時器/計數(shù)器比較匹配中斷
SIG_OVERFLOW2 定時器/計數(shù)器2 溢出中斷
SIG_INPUT_CAPTURE1 定時器/計數(shù)器2 輸入捕獲中斷
SIG_OUTPUT_COMPARE1A 定時器/計數(shù)器1 比較匹配A
SIG_OUTPUT_COMPARE1B 定時器/計數(shù)器1 比較匹配B
SIG_OVERFLOW1 定時器/計數(shù)器1 溢出中斷
SIG_OVERFLOW0 定時器/計數(shù)器0 溢出中斷
SIG_SPI SPI 操作完成中斷
SIG_UART_RECV USART 接收完成
SIG_UART_DATA USART 寄存器空
SIG_UART_TRANS USART 發(fā)送完成
SIG_ADC ADC轉(zhuǎn)換完成
SIG_EEPROM_READY E2PROM 準備就緒
SIG_COMPARATOR 模擬比較器中斷
SIG_2WIRE_SERIAL TWI 中斷
SIG_SPM_READY 寫程序存儲器準備好
*/
/*
本程序為編碼器調(diào)節(jié)電壓,能校對:輸出電壓,輸入電壓,與校對調(diào)節(jié)輸出的電壓值,
同時按下FUN與SET會進去校對,
本程序給出了一個簡單的應(yīng)用,其實可能用在任何電源上,只要你的電源有一個PWM輸出調(diào)節(jié)就行,因為它有校對功能嘛
輸出電壓校對:Vo_xiao
先用萬用表測到輸入電壓,然后把這電壓值輸進程序(通過編碼器調(diào)節(jié))然后按SET鍵,校對完成.
輸入電壓校對:Vi_xiao
與輸出電壓校對方法一樣,
調(diào)節(jié)輸出的電壓值:PO_xiao(配合輸出電壓顯示校對,校之前先把輸出電壓顯示校好)
L_X為下限電壓校對,不般不怎么校,只要調(diào)編碼器輸出為0V就行,除非你的電源有負電壓 VO 為你調(diào)節(jié)的電壓輸入值,由機內(nèi)輸入電壓采集
L_H 為上限電壓校對,可以在任意點電壓值上校對,程序會自動算出最高電壓上限值,比如,你用5V來校對,調(diào)整VO顯示到5V 這時按SET鍵,就校對完成了.
E_mail : veryjc@gmail.com
*/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#define PWM_our OCR1A
#define PWM OCR1B
#include "lcdinf.c"
#define V_max 300
#define di di1=10;
#define DLD di1=20;di2=60;di3=20
#define DIH PORTD|=0x80
#define DIL PORTD&=0x7f
#define key_in (~PINA)
uch di1,di2,di3;
uch tep2;
uch ks,ks2;
#define set 0x80
#define fun 0x40
//參數(shù)的地址
#define vihas 0
#define vohas 2
#define volas 4
#define pohas 6
#define polas 8
#define poas 10
char *ch_sp;
uch ch_x;
uch ch_s=1;
uch key;//按鍵;
uch int_;//編碼
uch up;//加十標(biāo)志
uch make;
unsigned long power;//輸出電壓值
uint power_max;//當(dāng)前最大電壓設(shè)置
uint vi;//輸出電壓
uint vo;//輸出電壓值
uint va;//輸出電流值
uint vi2;//輸出電壓
uint vo2;//輸出電壓值
uint va2;//輸出電流值
uint adc_1,adc_2,adc_3;
uint vo_a[10];//三個變量的數(shù)組
uint vi_a[10];
uint va_a[10];
uint vi_kh;//每能道的修正系數(shù)
uint vo_kh;
uint vo_kl;
uint po_kh;
uint po_kl;
//----------------------
uch xiao;
uint adc_maxmin(uint *xp,uch _tep){
unsigned char i;
int ret;
int ret_tep;
unsigned char max_id,min_id,max_value,min_value;
ret=0;
for(i=1;i<10;i++)
ret+=*(xp+i);
//找到最大和最小值索引
ret/=10;
max_id=min_id=1;
max_value=min_value=0;
for(i=1;i<10;i++)
{
if(*(xp+i)>ret)
{
if(*(xp+i)-ret>max_value)
{
max_value=*(xp+i)-ret;
max_id=i;
}
}
else
{
if(ret-*(xp+i)>min_value)
{
min_value=ret-*(xp+i);
min_id=i;
}
}
}
//去掉第一個和最大最小值后的平均值
ret=0;
for(i=1;i<10;i++)
{
if((i!=min_id)&&(i!=max_id))
ret+=*(xp+i);
}
if(min_id!=max_id)
ret/=7;
else
ret/=8;
return ret;
}
void adc_sy(void){
static uch x,y;
if(x>10){
x=0;
if(y<10){
vo_a[y]=adc_1;
vi_a[y]=adc_2;
va_a[y]=adc_3;
y++;
}
else y=0;
}
else x++;
if(y==10){
vo2=adc_maxmin(vo_a,1);
vi2=adc_maxmin(vi_a,2);
va2=adc_maxmin(va_a,3);
y=0;
}
}
SIGNAL(SIG_ADC)
{
if(ADMUX==0xC0){ADMUX=0xC1;adc_1=ADC;return;}
if(ADMUX==0xC1){ADMUX=0xC0;adc_2=ADC;return;}
//if(ADMUX==0xC2){ADMUX=0xC0;adc_3=ADC;return;}
}
SIGNAL(SIG_OVERFLOW0)
{
ADCSRA|=_BV(ADSC);
uch tep;
tep=key_in&0xc0;
ks2=tep;
xiao=tep;
if(tep){
if(ks==10){tep2=tep;ks++;}
else ks++;
}
else{ks=0;if(tep2){key=tep2;make=1;}tep2=0;}
if(ch_s){
w_by(*ch_sp);ch_s=0;
if(ch_x<15){ch_x++;ch_sp++;}
else {ch_x=0;ch_sp=&xy_ch;}
}
else {xini(ch_x);ch_s=1;}
if(di1){DIL;di1--;}//第一次響
else {
if(di2){di2--;DIH;}//第二次延時
else {if(di3){di3--;DIL;}else DIH;}//第三次響
}
TCNT0=250;//20MS
// power++;
}
uch s_up;
uch s_down;
SIGNAL(SIG_INTERRUPT0){
make=1;
if((PIND&0x0c)==0x0c)return;
if(s_down){s_down=0;return;}
s_up=1;
int_=1;
}
SIGNAL(SIG_INTERRUPT1){
make=1;//有修改
if((PIND&0x0c)==0x0c)return;
if(s_up){s_up=0;return;}
s_down=1;
int_=2;
}
void daly(void){
uch x,y;
for(x=100;x!=0;x--);
for(y=250;y!=0;y--)for(x=250;x!=0;x--);
}
void ini(void){
PORTD=0xff;
PORTB=0xff;
DDRB=0xff;
DDRC=0xff;
DDRA=0x0;
DDRD=0xf0;
daly();
cli();
c_b(ASSR,AS2);
s_b(MCUCSR,JTD);s_b(MCUCSR,JTD);//關(guān)閉JTAG
ADMUX=0xC0;//選擇第七通道換轉(zhuǎn)
ADCSRA=_BV(ADEN)|_BV(ADSC)|_BV(ADPS0)|_BV(ADSC)|_BV(ADIE);
GICR=0xc0;//設(shè)置中斷
MCUCR=0x0f;
TCCR0=(1<<CS02)|(1<<CS00);
TCCR1A=(1<<WGM11)|0xa0;
TCCR1B=(1<<WGM13)|(1<<CS10);//
ICR1=2000;
lcdini();
ch_sp=&xy_ch;
ch_x=0;
xini(0);
dlay(80);
TCNT0=220;
TIMSK=(1<<TOIE0);
sei();
}
uch dip;//小數(shù)點
uch shu_z;//符號
uch _shu[6];
void shu_f(int x){
uint tep;
if(x<0){shu_z=1;x=~x+1;}
_shu[3]=x/1000;
tep=x%1000;
_shu[2]=tep/100;
x=tep%100;
_shu[1]=x/10;
_shu[0]=x%10;
}
void di_OA(int x,uch a){//下行顯示電流
shu_f(x);
xy_ch[a][0]='V';
xy_ch[a][1]='A';
xy_ch[a][2]=':';
xy_ch[a][3]=ascii_s(_shu[2]);
xy_ch[a][4]='.';
xy_ch[a][5]=ascii_s(_shu[1]);
xy_ch[a][6]=ascii_s(_shu[0]);
xy_ch[a][7]='A';
}
void di_VI(int x,uch a){//下行顯示輸入電壓
shu_f(x);
xy_ch[a][0]='V';
xy_ch[a][1]='I';
xy_ch[a][2]=':';
xy_ch[a][3]=ascii_s(_shu[2]);
xy_ch[a][4]=ascii_s(_shu[1]);
xy_ch[a][5]='.';
xy_ch[a][6]=ascii_s(_shu[0]);
xy_ch[a][7]='V';
}
void di_Vo(int x,uch a){//下行顯示輸出電壓
shu_f(x);
xy_ch[a][0]='V';
xy_ch[a][1]='o';
xy_ch[a][2]=':';
xy_ch[a][3]=ascii_s(_shu[2]);
xy_ch[a][4]=ascii_s(_shu[1]);
xy_ch[a][5]='.';
xy_ch[a][6]=ascii_s(_shu[0]);
xy_ch[a][7]='V';
}
void di_Vout(int x,uch a){//下行顯示輸入電壓
shu_f(x);
xy_ch[a][0]='V';
xy_ch[a][1]='O';
xy_ch[a][2]=':';
xy_ch[a][3]=ascii_s(_shu[2]);
xy_ch[a][4]=ascii_s(_shu[1]);
xy_ch[a][5]='.';
xy_ch[a][6]=ascii_s(_shu[0]);
if(up)xy_ch[0][7]='V';
else xy_ch[0][7]='+';
}
void di_AD(int x,uch a){//下行顯示輸入電壓
shu_f(x);
xy_ch[a][0]='A';
xy_ch[a][1]='D';
xy_ch[a][2]=':';
xy_ch[a][3]='!';
xy_ch[a][4]=ascii_s(_shu[3]);
xy_ch[a][5]=ascii_s(_shu[2]);
xy_ch[a][6]=ascii_s(_shu[1]);
xy_ch[a][7]=ascii_s(_shu[0]);
}
/*---------------量程式轉(zhuǎn)換數(shù)學(xué)模型號--------------*/
int moxin(int ouh,int oul,int inh,int inl,int x){
//inx為轉(zhuǎn)換前的量程式,oux為轉(zhuǎn)換后的量程,x為轉(zhuǎn)換前的變化值
//數(shù)學(xué)模型返回值=(ouh-oul)*(x-inl)/(inh-inl)+oul
long y;
long x1,x2,x3;
x1=ouh-oul;
x2=x-inl;
x3=inh-inl;
y=x1*x2;
y=y/x3+oul;
return (int)y;
}
void vi_xiao(void){//輸入電壓校對
uint tep_vi;
tep_vi=vi;
uint tep1;
long x1,x2,x3;
while(1){
adc_sy();
di_VI(tep_vi,0);
di_AD(vi2,1);//430
if(int_==1){if(tep_vi<V_max)tep_vi++;int_=0;}
if(int_==2){if(tep_vi>0)tep_vi--;int_=0;}
if(key==set)
{
key=0;
tep1= moxin(1024,0,V_max,0,tep_vi);//值對應(yīng)電壓值
x1=tep1;
x2=vi2;
x3=1024*x2/x1;
vi_kh=(unsigned int)x3;
eeprom_write_word(vihas,vi_kh);
tep1= moxin(1024,0,vi_kh,0,vi2);
vi= moxin(V_max,0,1024,0,tep1);
di_VI(vi,1);
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
}
if(key==fun){key=0;return;}
}
}
void vo_xiao(void){//輸入電壓校對
uint tep_vo;
tep_vo=vo;
uint tep1;
long x1,x2,x3;
PWM_our=300;
while(1){
adc_sy();
di_Vo(tep_vo,0);
di_AD(vo2,1);//430
if(int_==1){if(tep_vo<V_max)tep_vo++;int_=0;}
if(int_==2){if(tep_vo>0)tep_vo--;int_=0;}
if(key==set)
{
key=0;
tep1= moxin(1024,0,V_max,0,tep_vo);//值對應(yīng)電壓值
x1=tep1;
x2=vo2;
x3=1024*x2/x1;
vo_kh=x3;
eeprom_write_word(vohas,vo_kh);
tep1= moxin(1024,0,vo_kh,0,vo2);
vo= moxin(V_max,0,1024,0,tep1);
di_Vo(vo,1);
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
}
if(key==fun){key=0;return;}
}
}
void po_xiao(void){//輸入電壓校對
uint mo_tep;
uch out_s;
uint po_tep;
out_s=1;
PWM_our=po_kl;
while(1){
shu_f(PWM_our);
xy_ch[0][1]='_';
xy_ch[0][2]='X';
xy_ch[0][3]=' ';
xy_ch[0][4]=ascii_s(_shu[3]);
xy_ch[0][5]=ascii_s(_shu[2]);
xy_ch[0][6]=ascii_s(_shu[1]);
xy_ch[0][7]=ascii_s(_shu[0]);
if(out_s==1){
xy_ch[0][0]='L';
if(key==set){
out_s=0;
key=0;
po_kl=PWM_our;
eeprom_write_word(polas,po_kl);
di_AD(po_kl,0);
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
PWM_our=666;
}
}
else {
xy_ch[0][0]='H';
if(key==set){out_s=1;
key=0;
po_tep=moxin(2000,0,V_max,0,vo);
po_kh=moxin(2000,0,PWM_our,po_kl,po_tep);
eeprom_write_word(pohas,po_kh);
di_AD(po_kh,0);;
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
daly();daly();daly();
PWM_our=po_kl;
}
}
adc_sy();
mo_tep= moxin(1024,0,vo_kh,0,vo2);
vo= moxin(V_max,0,1024,0,mo_tep);
di_Vo(vo,1);
if(int_==1){if(PWM_our<2000)PWM_our++;int_=0;}
if(int_==2){if(PWM_our>0)PWM_our--;int_=0;}
if(key==fun){key=0;return;}
}
}
char xiao_chs[][8]={//上行
{"Vi_Xiao ",},
{"Vo_Xiao ",},
{"PO_Xiao ",},
};
void pwxd(void){//校對
uch tep;
uch cs_fun;
xy_ch[0][0]='X';
xy_ch[0][1]='i';
xy_ch[0][2]='a';
xy_ch[0][3]='o';
xy_ch[0][4]=' ';
xy_ch[0][5]='D';
xy_ch[0][6]='u';
xy_ch[0][7]='i';
xy_ch[1][0]=' ';
xy_ch[1][1]=' ';
xy_ch[1][2]=' ';
xy_ch[1][3]=' ';
xy_ch[1][4]=' ';
xy_ch[1][5]=' ';
xy_ch[1][6]=' ';
xy_ch[1][7]=' ';
st:
if(key==0)goto st;
daly();
key=0;
cs_fun=0;
tep=0;
while(1){
if(tep){
if(int_==1){if(cs_fun<2)cs_fun++;int_=0;}
if(int_==2){if(cs_fun>0)cs_fun--;int_=0;}
dis_chs(&xiao_chs[cs_fun],0);
dis_chs("OK?_SET ",1);
if(key==set){
key=0;
if(cs_fun==0)vi_xiao();
if(cs_fun==1)vo_xiao();
if(cs_fun==2)po_xiao();
}
}
else{
xy_ch[1][0]='O';
xy_ch[1][1]='K';
xy_ch[1][2]='?';
xy_ch[1][3]=' ';
xy_ch[1][4]=' ';
xy_ch[1][5]=' ';
xy_ch[1][6]=' ';
xy_ch[1][7]=' ';
if(key==set){tep=1;key=0;}
}
if(key==fun){key=0;return;}
}
}
int main(void){
uint eep_daly;
uch cs;//下行顯示模試
uch y;
uint pwm_tep;
unsigned long pwm_tep_s;
uint temp;
uint mo_tep;
ini();
power_max=V_max;
up=1;
cs=0;
//讀取修正系數(shù)
vi_kh=eeprom_read_word(vihas);
vo_kh=eeprom_read_word(vohas);
vo_kl=eeprom_read_word(volas);
po_kh =eeprom_read_word(pohas);
po_kl=eeprom_read_word(polas);
power=eeprom_read_word(poas);
if(vi_kh>1500){vi_kh=1024;eeprom_write_word(vihas,vi_kh);}
if(vo_kh>1500){vo_kh=1024;eeprom_write_word(vohas,vo_kh);}
if(vo_kl>1500){vo_kl=0;eeprom_write_word(volas,vo_kl);}
if(po_kh>2000){po_kh=2000;eeprom_write_word(pohas,po_kh);}
if(po_kl>2000){po_kl=0;eeprom_write_word(polas,po_kl);}
if(power>300){power=0;eeprom_write_word(poas,power);}
// vi_kh=1000;
DLD;
while(1){
if(make){make=0;di;
eep_daly=0;
}
if(eep_daly>8000){eeprom_write_word(poas,power);}//累積到8000時保存POWER值
else eep_daly++;
pwm_tep_s=power*2000/V_max;
PWM_our=moxin(2000,0,po_kh,0,pwm_tep_s);
//PWM_our=pwm_tep_s;
/*
if(pwm_tep!=pwm_tep_s){
if(pwm_tep<pwm_tep_s)pwm_tep+=1;
else pwm_tep-=1;
}
*/
if(key==set){if(up)up=0;else up=1;key=0;}
if(key==fun){if(cs<1)cs++;else cs=0;key=0;}
if(int_==1){if(power<(vi-5))if(up)power++;else power+=10;if(power>(vi-5))power=(vi-5);int_=0;}
if(int_==2){if(power>0)if(up)power--;else power-=10;if(power>(vi-5))power=0;int_=0;}
if(xiao==0xc0){if(temp<500)temp++;else {di1=200;key=0;pwxd();}}else temp=0;
di_Vout(power,0);
mo_tep= moxin(1024,0,vi_kh,0,vi2);
vi= moxin(V_max,0,1024,0,mo_tep);
switch (cs)
{
case 0 :
di_VI(vi,1);
break;
case 1 :
mo_tep= moxin(1024,0,vo_kh,0,vo2);
vo= moxin(V_max,0,1024,0,mo_tep);
di_Vo(vo,1);break;
default :break;
}
adc_sy();
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -