大家好!我是菜鸟,目前在学单片机特别崇拜尤小翠大师的这篇单片机的逆变器http://bbs.dianyuan.com/topic/916798,我看了N遍程序终于能看懂一点点了,但是我没有现成的STC12C5410AD的单片机,但手中有一个STC12C5A60S2的单片机。我是想把STC12C5410AD的程序改为STC12C5A60S2用,我改了头文件后报错SPWM2 SPWM3,于是我根据程序对照2个单片机的PDF资料,发现自带AD中的寄存器也不同5410的ADC_DATA和5A60S2的RES不一样,我就把源程序呢里AD寄存器的ADC_DATA改为RES,具体修改的程序待会我贴出来。我是想问我这样修改程序为STC12C5A60S2可以直接用吗?同时希望有哪个高手有尤小翠的这程序的配套电路图吗?能给我一份吗?修改后的程序:
#include "STC12C5A60S2.H"
#include "math.h"
#include "intrins.h"
sbit beep=P3^4;
sbit stop=P3^3;
sbit stopo=P3^2;
sbit short_protection=P2^3;
sbit short_indicator=P2^4;
sbit hv_indicator=P1^5;
sbit lv_indicator=P1^6;
sbit w_indicator=P1^7;
#define FOSC 12000000L //System Clock Frquency(12MHz)
#define BAUD 2400 //UART baudrate 2400
#define v_c 724 //
#define Protection_time 10 //
#define Kp 5
#define Ki 0
#define Kd 0
#define sf 77
#define AD_FEEDBACK 1 //Output Voltage Feedback
#define AD_BATTERY 0 //Battery Voltage Watcher
#define MIN_BAT 9 //Mininum Battery Voltage
#define MAX_BAT 15 //Maxium Battery Voltage
#define WARN_BAT 10 //Low Battery Warning Voltage
#define MAX_IOUT 5 //Maxium Output Current
#define MAX_VOUT 245 //Maxium Output Voltage
#define MIN_VOUT 200 //Mininum Output Voltage
#define PW_SHORT 10 //Pulse Width when short occurs
#define NONE_PARITY 0
#define ODD_PARITY 1
#define EVEN_PARITY 2
#define MARK_PARITY 3
#define SPACE_PARITY 4
#define PARITYBIT EVEN_PARITY
typedef unsigned char BYTE;
typedef unsigned int WORD;
unsigned int m,pwm_1,pwm_2,vr; //用m来控制整体占空比//
int k=0,i,j,pwm1,pwm2,t=0;
unsigned char code pwm[159]={0,4,8,13,17,21,25,29,34,38,42,46,50,54,59,63,67,71,75,79,83,86,90,94,98,102,105,109,113,116,120,123,127,130,134,137,140,143,147,150,153,156,159,161,164,167,170,172,175,177,179,182,184,186,188,190,192,194,196,198,199,201,203,204,205,207,208,209,210,211,212,213,213,214,214,215,215,216,216,216,216,216,216,215,215,214,214,213,213,212,211,210,209,208,207,205,204,203,201,199,198,196,194,192,190,188,186,184,182,179,177,175,172,170,167,164,161,159,156,153,150,147,143,140,137,134,130,127,123,120,116,113,109,105,102,98,94,90,86,83,79,75,71,67,63,59,54,50,46,42,38,34,29,25,21,17,13,8,4};
bit busy;
char itc_result[3];
int v_bat,v_out;
unsigned char protecting;
bit esend=0;
//INT to CHAR//
void inttochar(unsigned int num){
itc_result[0]=num/100+48;
itc_result[1]=(num/10)%10+48;
itc_result[2]=num%10+48;
}
//延时函数//
void delay(unsigned int time){
unsigned int a=0,b;
for(a=0;a
//PWM initiallize//
void pwm_init(){
CMOD=0X02; //设置PCA计数器工作频率为F/2//
CCON=0X00; //清0计数器和溢出标志位
CL=0X00;//计数器高8位和低八位清0
CH=0X00;
CCAPM0=0X42; //设置PWM口//
CCAPM1=0X42;
//CCAPM2=0X42;//以下两句是被我注释掉的,5A60S2没有此功能
//CCAPM3=0X42;
CCAP0L=0X00;
CCAP0H=0X00;
CCAP1L=0X00;
CCAP1H=0X00;
//CCAP2L=0X00;//以下4句被我注释掉的,5A60S2没有此功能
//CCAP2H=0X00;
//CCAP3L=0X00;
//CCAP3H=0X00;
CR=1;//开启PCA计数器
}
//Timer initiallize//
void time_init()
{
#if(PARITYBIT==NONE_PARITY)
SCON=0x50;
#elif (PARITYBIT==ODD_PARITY)||(PARITYBIT==EVEN_PARITY)||(PARITYBIT==MARK_PARITY)
SCON=0xDA;
#elif (PARITYBIT==SPACE_PARITY)
SCON=0xD2;
#endif
TMOD=0X00;//定时器0工作模式0//
TMOD|=0x20;
ET0=1; //开启定时器0中断
TH0=0XFE;
TL0=0X09; //160点晶振12M,50Hz*2*159=15900Hz 调整TL0使输出频率为50HZ//
TR0=1开启定时器0//
TH1=TL1=-(FOSC/12/32/BAUD);
TR1=1;
ES=1;
}
//发送数据//
void SendData(BYTE dat)
{
while(busy);
ACC=dat;
if(P)
{
#if(PARITYBIT==ODD_PARITY)
TB8=0;
#elif(PARITYBIT==EVEN_PARITY)
TB8=1;
#endif
}else{
#if(PARITYBIT==ODD_PARITY)
TB8=1;
#elif(PARITYBIT==EVEN_PARITY)
TB8=0;
#endif
}
busy=1;
SBUF=ACC;
}
//发送字符串void SendString(char *s)
{
while(*s)
{
SendData(*s++);
}
}
//UART串口//
void Uart_Isr() interrupt 4 using 1
{
if(RI)
{
RI=0;
esend=1;
}
if(TI)
{
TI=0;
busy=0;
}
}
//软启动
void soft_start(void)
{
m=0;
do{
m=m+27;
delay(12);
}
while(m<210);
}
//AD初始化//
void AD_init()
{
P1ASF=0X04;//设置5A60S2的P1.2为AD功能
//P1M0=0X07;//以下为三个5410AD功能设置
//P1M1=0XF0;
//P1=0xFF; //设置P1口为高阻输出//
ADC_CONTR = 0x80|0x00; //270个时钟周期转换一次//
delay(4);
}
//AD采样函数//
//AD 转换0------7对应P1.0到P1.7,0----charge,1---u_bat,2---0ut,3---input,4---load//
unsigned int ad(unsigned char i)
{
ADC_RES =0;//被我修改为5A60S2的寄存器
//ADC_DATA=0;//源程序代码被我注释了
//ADC_LOW2=0;//源程序已经注释
ADC_CONTR=0x80|0x00|i|0x08;//0000,1010开启AD转换P1.2//
_nop_();
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR&0X10));//等待转换结束//
ADC_CONTR&=~0x10;
return ADC_RES;//ADC_DATA;
}
//SPWM实现//
void int_time0(void) interrupt 1{
TH0=0XFE;
TL0=0X09;//重装初值//
TR0=1;
CCAP0H=pwm1;
//CCAP2H=pwm1;
CCAP1H=pwm2; //装入脉宽 //
CCAP3H=pwm2;
k++;
if(k<159)
{//正半周//
i=k;
if(protecting==0){
pwm_1=m*pwm[i]/216;
pwm1=(unsigned char)pwm_1;
}
else{
pwm1=0;
}
pwm2=0;
}
else if(k<318){//负半周//
j=k-159;
pwm1=0;
if(protecting==0){
pwm_2=m*pwm[j]/216;
pwm2=(unsigned char)pwm_2;
}
else{
pwm2=0;
}
pwm1=0;
}
else{//周期结束//
k=0;
i=k;
if(protecting==0){
pwm_1=m*pwm[i]/216;
pwm1=(unsigned char)pwm_1;
}
else{
pwm1=PW_SHORT;
}
pwm2=0;
vr=ad(AD_FEEDBACK);
if (fabs(vr-79)>3){
if (vr>79)
m=m-4;
else
m=m+4;
}
if (m>255)
m=255;
if (m<1)
m=1;
if(t<10) //指示灯闪烁计时
t++;
v_out=vr*v_c/256;
v_bat=ad(AD_BATTERY)*400/256; //取10倍电池电压的值
}
}
//主程序//
void main()
{
//初始化P3//
P3M0=0x00;
P3M1=0x10;
beep=0;
stop=0;
stopo=1;
short_indicator=0;
hv_indicator=0;
lv_indicator=0;
w_indicator=0;
protecting=0;
//各种初始化//
pwm_init();
time_init();
AD_init();
EA=1;
soft_start();
m=216; //m初始值//
SendString("ready\r\n");
while(1){ //死循环
if((stop==1)|((v_bat<(10*MIN_BAT)))|(v_bat>(10*MAX_BAT))|(short_protection==0))
{ //电池电压异常或者输出短路或者外部要求停止报警
beep=1;
}
else{
beep=0;
}
if((stop==1)|((v_bat<(10*MIN_BAT)))|(v_bat>(10*MAX_BAT)))
{ //电池电压异常或者外部要求停止时关闭输出
stopo=0;
}
else{
stopo=1;
}
//输出电压检测
if (v_out { //低压 if(t==10){ w_indicator=1; } //短路动作 if(short_protection==0){ lv_indicator=(v_bat<(10*MIN_BAT)); //清0闪烁计数器 if(t==10) t=0;
w_indicator=~w_indicator;
}
}
else{
if (v_out>MAX_VOUT){ //过压
}
else{
w_indicator=0; //正常
}
protecting=Protection_time;
}
if(protecting==0){
short_indicator=0;
}
else{
short_indicator=1;
if (short_protection==1)
if(t==10)
protecting-=1;
}
//电压指示
if (((10*MIN_BAT)
lv_indicator=~lv_indicator;
}
hv_indicator=(v_bat>(10*MAX_BAT));
if(esend==1){
esend=0;
inttochar(v_bat);
SendString("in:");
SendString(itc_result);
inttochar(v_out);
SendString("vout:");
SendString(itc_result);
SendString("\r\n");
}
}
}