大家好!我是菜鳥,目前在學(xué)單片機特別崇拜尤小翠大師的這篇單片機的逆變器http://bbs.dianyuan.com/topic/916798,我看了N遍程序終于能看懂一點點了,但是我沒有現(xiàn)成的STC12C5410AD的單片機,但手中有一個STC12C5A60S2的單片機。我是想把STC12C5410AD的程序改為STC12C5A60S2用,我改了頭文件后報錯SPWM2 SPWM3,于是我根據(jù)程序?qū)φ?個單片機的PDF資料,發(fā)現(xiàn)自帶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;
}
//延時函數(shù)//
void delay(unsigned int time){
unsigned int a=0,b;
for(a=0;a
//PWM initiallize//
void pwm_init(){
CMOD=0X02; //設(shè)置PCA計數(shù)器工作頻率為F/2//
CCON=0X00; //清0計數(shù)器和溢出標志位
CL=0X00;//計數(shù)器高8位和低八位清0
CH=0X00;
CCAPM0=0X42; //設(shè)置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計數(shù)器
}
//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 調(diào)整TL0使輸出頻率為50HZ//
TR0=1開啟定時器0//
TH1=TL1=-(FOSC/12/32/BAUD);
TR1=1;
ES=1;
}
//發(fā)送數(shù)據(jù)//
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;
}
//發(fā)送字符串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;//設(shè)置5A60S2的P1.2為AD功能
//P1M0=0X07;//以下為三個5410AD功能設(shè)置
//P1M1=0XF0;
//P1=0xFF; //設(shè)置P1口為高阻輸出//
ADC_CONTR = 0x80|0x00; //270個時鐘周期轉(zhuǎn)換一次//
delay(4);
}
//AD采樣函數(shù)//
//AD 轉(zhuǎn)換0------7對應(yīng)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;//源程序已經(jīng)注釋
ADC_CONTR=0x80|0x00|i|0x08;//0000,1010開啟AD轉(zhuǎn)換P1.2//
_nop_();
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR&0X10));//等待轉(zhuǎn)換結(jié)束//
ADC_CONTR&=~0x10;
return ADC_RES;//ADC_DATA;
}
//SPWM實現(xiàn)//
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{//周期結(jié)束//
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){ //死循環(huán)
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)))
{ //電池電壓異?;蛘咄獠恳笸V箷r關(guān)閉輸出
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閃爍計數(shù)器 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");
}
}
}