请问会ATmege16单片机的变成么 有原理图 也有protel电路图 不用仿真出来 就要程序代码就行 加Q405902252

如题所述

第1个回答  2011-05-27
#include <iom16v.h>
#include <macros.h>
#include <stdio.h>
#include <RD_UseAvrPortBit.h>
#include <RD_UseBITs.h>
#include "delay.h"
#define uint unsigned int
#define uchar unsigned char
#define lint unsigned long
#define samping_batt 0x20
#define samping_cap 0x21
#define fixed_bc_volt0 7
//#define fixed_bc_volt1 20
#define fixed_cb_volt 0
uchar batt_volt0,batt_volt1,cap_volt0;
uint batt_volt0_temp,batt_volt1_temp,cap_volt0_temp;
uchar flag_c=0,flag_nc=0,flag_b=0,flag_nb=0,flag_ncharge=0,frist_charge_flag = 0;
uchar timecount,ad_timeflag=1;
////////////////////////////////////////////////////////////////////////////////
void port_init(void)
{
PORTB = 0x00; //数据寄存器
DDRB = 0x02; //PB1 out数据方向寄存器0为输入口
PORTC = 0x00;
DDRC = 0x00;
PORTD = 0xFF;
DDRD = 0xFF;//Hi_Z
}

//ADC initialize
// Conversion time: 6uS
void adc_init(void)
{
ADCSRA = 0x00; //disable adc
ADMUX = 0x20; //chanel 0 ,AREF and left order 8 bit,AD转换结果左对齐
//ADMUX = 0x00;//10bit
ACSR = 0x80; //disable ACD模拟比较器禁用
ADCSRB = 0x00; //连续转换模式
ADCSRA = 0x96; //enable ADC and clear ADCIF 128 pscan——1001 0110:启动ADC,ADC中断标志,ADC预分频64.
}

//Watchdog initialize
// prescale: 128K 1s
void watchdog_init(void)
{
WDR (); //this prevents a timeout on enabling复位看门狗
WDTCSR |= (1<<WDCE) | (1<<WDE);/* 30-Oct-2006 Umesh*/ 看门狗修改使能,四个周期后自动清零。看门狗系统复位使能,
WDTCSR = 0x1E; //WATCHDOG ENABLED - dont forget to issue WDRs——0001 1110
} //看门狗修改使能,看门狗系统复位使能,振荡周期128K,溢出时间1.0S。

//call this routine to initialize all peripherals
//TIMER0 initialize - prescale:1
// WGM: PWM Fast
// desired value: 46.875KHz
// actual value: 46.875KHz (0.00%)
void timer0_init(void)
{
TCCR0B = 0x00; //stop——WGM02=0,无时钟,TC不工作。
TCNT0 = 0x01; //set count——0000 0001
OCR0A = 0x00;
TCCR0A = 0xC3; //1100 0011:WGM01,0=11,011快速PWM模式,TOP=0xFF;COM0A1:0=11,比较匹配发生时OC0A置位,计数到TOP是OC0A清零。
//TCCR0B = 0x01; //start timer COM0B1:0=00,正常的端口操作,OC0B未连接。
}

// TIMER2 initialize - prescale:1024
// WGM: Normal
// desired value: 10mSec
// actual value: 9.984mSec (0.2%)
// Crystal: 12.0000Mhz
void timer2_init(void)
{
TCCR2B = 0x00; //stop——WGM22波形产生模式=0;无时钟,TC不工作。
ASSR = 0x00; //set async mode异步状态寄存器=0,各位可以写入新值。
TCNT2 = 0x8B; //setup 8B@12MHz D9@4MHz——1000 1011,139
//OCR2A = 0x75;——117
//OCR2B = 0x00;——0
TCCR2A = 0x00; WGM21:0=00,普通工作模式,COM2A1:0=00,COM2B1:0=00正常的端口操作,OC2A,OC2B未连接。
//TCCR2B = 0x07; //start
}

void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts全局中断禁用
port_init();//初始化端口
watchdog_init();//初始化看门狗
timer0_init();//初始化定时器0
timer2_init();//初始化定时器2
adc_init();//初始化AD

MCUCR = 0x00;//不禁用上拉电阻
EICRA = 0x00; //extended ext ints外部中断控制寄存器,INT1为低电平时产生中断请求,INT0为低电平时产生中断请求。
EIMSK = 0x00;//外部中断屏蔽寄存器,外部中断请求使能位INT0,INT1为0

TIMSK0 = 0x00; //timer 0 interrupt sources OCIE0A inturp enable
//TC0输出比较匹配AB中断使能=00,TC0溢出中断使能位=0.
TIMSK1 = 0x00; //timer 1 interrupt sources
//TC1输入捕捉中断使能=0;TC1输出比较AB匹配中断使能=00,TC1溢出中断使能=0.
TIMSK2 = 0x01; //timer 2 interrupt sources
//TC2输出比较匹配AB中断使能=00,TC2溢出中断使能=1

PCMSK0 = 0x00; //pin change mask 0 引脚变化屏蔽寄存器禁用
PCMSK1 = 0x00; //pin change mask 1
PCMSK2 = 0x00; //pin change mask 2
PCICR = 0x00; //pin change enable 引脚电平变化中断控制寄存器

PRR = 0x00; //power controller功耗抑制寄存器

SEI(); //re-enable interrupts全局中断开启。
//all peripherals are now initialized
}
////////////////////////////////////////////////////////////////////////////////
#pragma interrupt_handler timer2_ovf_isr:iv_TIM2_OVF
void timer2_ovf_isr(void)
{
TCNT2 = 0x8B; //reload counter value 8B 12MHz D9@4MHz
//if(ad_timeflag==1)
//ad_timeflag = 0; //10ms到停止AD采样
if(++timecount==170)
{
WDR ();
timecount = 0;
OCR0A = 0x00;
ad_timeflag = 1; //ad 可能采样
TCCR2B = 0x00; //stop time2
}
}
////////////////////////////////////////////////////////////////////////////////
//8位AD转换程序 admux_value为通道选择参数
int adconver(uchar admux_value)
{
uchar get_ad_value=0,i;
uint ad_value=0;
const uchar getad_value[255];
//ADCSRA = 0x97; //ADEN ADIF 1 128 prescan 69us @12MHz
ADMUX=admux_value;
for(i=0;i<255;i++)
{
WDR ();
ADCSRA|=BIT(ADSC); //启动ADC
while(ADCSRA&(1<<ADSC));
ADCSRA|=(1<<ADIF);
//get_ad_value=ADCL;
//get_ad_value|=(uint)(ADCH<<8);
get_ad_value=ADCH;
getad_value[i]=get_ad_value;
}
//ADCSRA = 0x00; //stop adc
for(i=1;i<255;i++)
{
ad_value+=getad_value[i];//丢弃第一次结果
}
ad_value/=254;
return (ad_value);
}
////////////////////////////////////////////////////////////////////////////////
//10位AD转换程序 admux_value为通道选择参数
/*int adconver(uchar admux_value)
{
uchar i;
uint get_ad_value=0,ad_value=0;
const uint getad_value[61];
ADMUX=admux_value;
for(i=0;i<61;i++)
{
ADCSRA|=BIT(ADSC); //启动ADC
while(ADCSRA&(1<<ADSC));
ADCSRA|=(1<<ADIF);
get_ad_value=ADCL;
get_ad_value|=(uint)(ADCH<<8);
getad_value[i]=get_ad_value;
}
for(i=1;i<61;i++)
{
ad_value+=getad_value[i];//丢弃第一次结果
}
ad_value=ad_value/60;
return (ad_value);
}*/
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void charge_control_cap(void)
{
if(flag_c==0)
{
//TCCR0B|= BIT(CS00); //start timer0
TCCR0B = 0x01; //TCCR0B = 0x02 8prescan =0x01 1prescan
OCR0A = 0x00;
PORTD |= BIT(PD0); //off SW1
flag_c = 1;
//flag_nc = 0;
//delay_ms(1000);
PORTB |=BIT(PB1); //on +12V_1
frist_charge_flag=0; //首次充电标志清零
}
else return;
}
void charge_control_ncap(void)
{
WDR ();
PORTB &=~BIT(PB1); //off +12V_1
OCR0A = 0x00;
TCCR0B = 0x00; //close timer0
PORTD |=BIT(PD6);
PORTD &=~BIT(PD0); //on SW1
}
///////////////////////////////////////////////////////////////////////////////
void scan_key(void)
{
WDR ();
//PORTD_0 = PINB_2;
PORTD_1 = PINB_3;
PORTD_2 = PINB_4;
PORTD_3 = PINB_5;
}
////////////////////////////////////////////////////////////////////////////////
main()
{
uchar charge_switch;
uint ocr0a_temp;
init_devices();
frist_charge_flag=0;
PORTB &=~BIT(PB1); //off +12V_1
delay_ms(80);
batt_volt0 = adconver(samping_batt); //samping Vbatte
batt_volt0_temp = batt_volt0*3/10; //实际电瓶电压值
while(1)
{
WDR ();
scan_key();
if(ad_timeflag==1)
{
delay_ms(10);
batt_volt1 = adconver(samping_batt); //samping Vbatte
batt_volt1_temp = batt_volt1*3/10; //实际电瓶电压值

cap_volt0 = adconver(samping_cap); //samping Vcap
cap_volt0_temp = cap_volt0*3/10; //实际电容电压值
if(batt_volt1_temp>cap_volt0_temp)
{
if((batt_volt1_temp-cap_volt0_temp)>3) //充电阀值压差4V
{
//charge_control_cap();

TCCR0B|= BIT(CS01);//(1<<CS01)|(1<<CS00); // on PWM BIT(CS01)5.89KHz@12MHz BIT(CS00)15.6KHz 1prescan@4MHz
PORTD |= BIT(PD0); //off SW1
PORTB |= BIT(PB1); //on +12V_1

charge_switch = cap_volt0_temp/5;
switch(charge_switch) //5V一个电压档次
{
case 0: //0~4.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp-20;//50
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

case 1: //5~9.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp-15;//75
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

case 2: //10~14.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp-10;//105
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

case 3: //15~19.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp-5;//135
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

case 4: //20~24.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp;//165
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

case 5: //25~29.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp;//195
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

case 6: //30~34.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp;//215
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

case 7: //35~39.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp-4;//221
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

case 8: //40~44.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp-9;//258
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

case 9: //45~49.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp-15;//279
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

case 10: //50~54.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp-21;//300
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

case 11: //55~59.9V
ocr0a_temp = ((fixed_bc_volt0+charge_switch*5)*255)/batt_volt0_temp-28;//320
if(ocr0a_temp>255)
OCR0A = 255;
else
OCR0A = ocr0a_temp;
break;

default:
charge_control_ncap();
break;
}
}
else
charge_control_ncap();
}
else
charge_control_ncap();

ad_timeflag = 0; //时间到后才能采样
TCCR2B = 0x07; //start timer2*/
}

}
}

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网