📄 main.c
字号:
/*eeprom_is_ready() //EEPROM 忙检测(返回EEWE 位)
eeprom_busy_wait() //查询等待EEPROM 准备就绪
uint8_t eeprom_read_byte (const uint8_t *addr) //从指定地址读一字节
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) //写一字节至指定地址
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 定时器/计数器比较匹配中断
SIG_OVERFLOW2 定时器/计数器2 溢出中断
SIG_INPUT_CAPTURE1 定时器/计数器2 输入捕获中断
SIG_OUTPUT_COMPARE1A 定时器/计数器1 比较匹配A
SIG_OUTPUT_COMPARE1B 定时器/计数器1 比较匹配B
SIG_OVERFLOW1 定时器/计数器1 溢出中断
SIG_OVERFLOW0 定时器/计数器0 溢出中断
SIG_SPI SPI 操作完成中断
SIG_UART_RECV USART 接收完成
SIG_UART_DATA USART 寄存器空
SIG_UART_TRANS USART 发送完成
SIG_ADC ADC转换完成
SIG_EEPROM_READY E2PROM 准备就绪
SIG_COMPARATOR 模拟比较器中断
SIG_2WIRE_SERIAL TWI 中断
SIG_SPM_READY 写程序存储器准备好
*/
/*
本程序为编码器调节电压,能校对:输出电压,输入电压,与校对调节输出的电压值,
同时按下FUN与SET会进去校对,
本程序给出了一个简单的应用,其实可能用在任何电源上,只要你的电源有一个PWM输出调节就行,因为它有校对功能嘛
输出电压校对:Vo_xiao
先用万用表测到输入电压,然后把这电压值输进程序(通过编码器调节)然后按SET键,校对完成.
输入电压校对:Vi_xiao
与输出电压校对方法一样,
调节输出的电压值:PO_xiao(配合输出电压显示校对,校之前先把输出电压显示校好)
L_X为下限电压校对,不般不怎么校,只要调编码器输出为0V就行,除非你的电源有负电压 VO 为你调节的电压输入值,由机内输入电压采集
L_H 为上限电压校对,可以在任意点电压值上校对,程序会自动算出最高电压上限值,比如,你用5V来校对,调整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
//参数的地址
#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;//加十标志
uch make;
unsigned long power;//输出电压值
uint power_max;//当前最大电压设置
uint vi;//输出电压
uint vo;//输出电压值
uint va;//输出电流值
uint vi2;//输出电压
uint vo2;//输出电压值
uint va2;//输出电流值
uint adc_1,adc_2,adc_3;
uint vo_a[10];//三个变量的数组
uint vi_a[10];
uint va_a[10];
uint vi_kh;//每能道的修正系数
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);//关闭JTAG
ADMUX=0xC0;//选择第七通道换转
ADCSRA=_BV(ADEN)|_BV(ADSC)|_BV(ADPS0)|_BV(ADSC)|_BV(ADIE);
GICR=0xc0;//设置中断
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;//小数点
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]);
}
/*---------------量程式转换数学模型号--------------*/
int moxin(int ouh,int oul,int inh,int inl,int x){
//inx为转换前的量程式,oux为转换后的量程,x为转换前的变化值
//数学模型返回值=(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);//值对应电压值
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);//值对应电压值
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;
//读取修正系数
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();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -