本帖最后由 牛东 于 2015-5-21 15:04 编辑
正在做一个无刷驱动程序,想到独立波特率发生器作串口通信,程序怎么都不成功,借鉴网上的程序也不行!!(注:用T1串口就可以)
#include<reg51.h> //包含文件预处理命令
//-------------------------串口独立波特率发生器的特殊寄存器地址定义--------------------------------
sfr AUXR=0x8E;
sfr BRT=0x9C;
//================================================
//使用串口独立波特率发生器
void uart_init()
{
//(注:用T1串口就可以)
/*SCON=0x50;
TMOD=(TMOD&0x0f)|0x20;
TH1=TL1=0xFD; //11.0592M 9600
TR1=1;*/
//用此段就不行!!
SCON=0x50;
AUXR=0x11;
BRT=0XFD; //11.0592M 9600
}
//=============================================
void send_byte(u8 dat)
{
SBUF=dat;
while(!TI); //等待TI变为1
TI=0; //TI清0
}
//==========================主函数===============================
void main()
{
uart_init();
while(1)
{
send_byte(get_ad_data(ch));
}
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
//------------------------------------------------------
//霍尔信号采集定义W=P12 V=P11 U=P10
//-------------------------------------------------------
//状态指示灯定义 LED=P27 ABS功能选择 ABS=P26
//刹车检测口定义 shache=p34 防盗检测定义 FD=P37
//--------------------------------------------------------------------------------------------------
#include<reg51.h> //包含文件预处理命令
sfr p2m0=0x95; //P2口I/Q输出模式控制位,本程序中将P2口中的6个PWM信号口设置成推挽输出
sfr p2m1=0x96; //P2口I/Q输出模式控制位,本程序中将P2口中的6个PWM信号口设置成推挽输出
//-------------------------AD转换要用到的特殊寄存器地址定义----------------------------------------
sfr adc_contr=0xc5; //定义AD转换控制寄存器地址
sfr adc_data=0xc6; //定义AD转换结果寄存器地址
sfr p1m0=0x91; //带有8路AD的P1口模式选择寄存器0定义地址,本程序中将带有AD转换的口设置成开漏
sfr p1m1=0x92; //带有8路AD的P1口模式选择寄存器1定义地址,本程序中将带有AD转换的口设置成开漏
//-------------------------PWM=p35输出要用到的特殊寄存器地址定义---------------------------------------------
sfr ccap1h=0xfb; //PCA模块1捕捉/比较寄存器高8位
sfr pca_pwm1=0xf3; //PCA模块1-PWM寄存器
sfr ccapm1=0xdb; //PCA模块1工作模式寄存器
sfr ch=0xf9; //PCA计数器高8位
sfr cl=0xe9; //PCA计数器低8位
sfr ccon=0xd8; //PCA控制寄存器
sfr cmod=0xd9; //PCA工作模式寄存器
//-------------------------串口独立波特率发生器的特殊寄存器地址定义--------------------------------
sfr AUXR=0x8E; //独立波特率发生器控制寄存器
sfr BRT=0x9C; //独立波特率发生器寄存器,装初值0xfd是9600;
//------------------------------------------------------------------
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned int u32;
//-----------------------define PWM regist----------------------------------
#define PWM_ON_OFF pca_pwm1
#define ON 0
#define OFF 1
#define ERROR 1
#define OK 0
#define PWM_DATA ccap1h
#define PWM_DISENABLE ccapm1&=0xfd
#define PWM_ENABLE ccapm1|=0x02
//------------ define ADC opration const for adc_conter----------------
#define ADC_POWER 0x80
#define ADC_FLAG 0x10
#define ADC_START 0x08
#define ADC_SPEED 0x00
//----------------------------IO定义----------------------------------
sbit cr=ccon^6; //PCA计数器控制位,1开0关
sbit epca_lvd=IE^6; //PCA中断允许控制位1开0关
sbit led_out=P2^7; //指示灯
sbit alarm_out=P3^3; //报警输出口
sbit speed_3_in=P3^1; //3段速度控制口
sbit cruise_in=P1^4; //巡航选择口
sbit ABS_in=P2^6; //ABS选择口,对地为ABS功能
sbit brake_in=P3^4; //刹车口定义,对地刹车
sbit guard_in=P3^7; //防盗检测口
sbit AH=P2^2;
sbit BH=P2^1;
sbit CH=P2^0;
sbit AL=P2^5;
sbit BL=P2^4;
sbit CL=P2^3;
//========================标志位===========================
u8 led_handle_flag=0;
u8 led_soft_start_flag=0;
u8 led_speed_flag=0;
u8 led_current_flag=0;
u8 led_hall_flag=0;
u8 led_out_flag=0;
u8 led_run_flag=0;
u8 led_mos_flag=0;
u8 led_int0_flag=0;
u8 led_wait_flag=0;
u8 speed_timer_flag=0; //测量速度T0计时开始
u8 soft_start_flag=0;
u8 speed_flag=0;
//========================数据变量===========================
u8 hall_data=0; //霍尔数据
u8 hall_data_now=0; //霍尔新数据
u8 pwm_data=0; //PWM值
u16 speed_count=0; //转速数据
u8 timer_speed_count=0; //转速检测定时器计数器
u8 second_3_block_count=0; //3秒堵转定时计数
u8 low_voltage_count=0; //电池欠压计数
u16 led_time=0;
u16 led_count=0;
u8 led_a=0;
u8 timer0_a=0;
u8 timer0_b=0;
u8 timer0_c=0;
u8 speed_a=0;
u16 overload_count=0;
u8 hall_data_table[6]={0,0,0,0,0,0,};//霍尔数据暂存区
//============================AD转换后PWM对照表==========================================================
u8 code pwm_out_table[256]= //实际一共256个元素
{
1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, //0~39 0.82V以下视为转把故障 40个
235,235,235,235,235, 235,235,235,235,235, //40~49视为转把归0 0.85V左右 10个有效数据
235,235,235,235,235, 235,235,235,235,235, 235,235,235,235,235, 235,235,235,235,235, 235,235,235,235,230,
230,230,230,230,230, 230,230,230,230,210, 210,210,210,210,200, 200,200,200,200,200, 195,195,195,190,190,
190,185,185,185,180, 180,180,175,175,175, 170,170,165,165,160, 160,155,155,150,150, 145,145,140,140,135,
135,130,130,125,125, 120,120,115,115,110, 110,105,105,100,100, 95,95,90,90,85, 85,80,80,75,75,
70,70,65,65,60, 60,55,55,50,50, 45,45,40,40,35, 35,30,30,25,25, 20,20,15,15,10,
0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0,//50~209 有效数据 0.85~3.7v 160个
1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,1,1, //210~250 4v以上视为转把故障 45个1
};
//=====================================================函数声明=====================================================================
void delay_ms(int t); void delay_us(int t); void all_bridge_off(); void up_bridge_on();
void down_bridge_on(); void pwm_out_on(u8 pd,u8 hd); void pwm_out_off(); void send_byte(u8 dat);
void system_init(); void dispel_noise(); void phase3_out(u8 hd); void int0_init();
void timer0_init(); void pwm_init(); void adc_init(); void other_init();
void handle_service(u8 ch3); void led(u8 led_number); void uart_init(); void show_ADC_result(u8 ch);
u8 get_ad_data(u8 ch);
u8 get_hall_data();
u8 speed_detect(u8 hdn);
u8 current_detect(u8 ch7);
u8 mosfet_check(u8 ch7);
u8 handle_detect(u8 ch3);
//===============================================
void system_init()
{
other_init();
pwm_init();
timer0_init();
int0_init();
adc_init();
uart_init();
}
//================================================
//使用串口独立波特率发生器
void uart_init()
{
/*SCON=0x50;//mode 1,8-bit UART, enable riceve
TMOD=(TMOD&0x0f)|0x20;//set t1 mode 2 for 8-bit auto reload
TH1=TL1=0xFD;//TH=TL=-(FOSC/12/32/BUND) BOUND=9600; FOSC=11.0592M
TR1=1;*/
SCON=0x50; //[bit6:5]SM1 SM2 = 1 0;[bit4]REN=1
AUXR=0x11; //[bit4]BRTR=1,允许独立波特率发生器运行;[bit0]SIBRS=1,独立波特率作为串口1的波特率发生器,此时定时器1释放
BRT=0XFD; //独特波特率发生器定时器(产生波特率9600)
}
//=============================================
void send_byte(u8 dat)
{
SBUF=dat;
while(!TI); //等待TI变为1
TI=0; //TI清0
}
//=============================================
void show_ADC_result(u8 ch)
{
//send_byte(ch);
send_byte(get_ad_data(ch));
}
//=============================================
void other_init()
{
P1=0xff;P2=0xc0;P3=0xdf;//1101=d 3个端口初始状态
p2m0=0xc0;p2m1=0xff;//将P2端的6个驱动口设置成强上拉推挽输出
}
//===================================================
void timer0_init()
{
TMOD=(TMOD&0xf0)|0x01; //MODE 1,16Bit
TH0=0x3c;TL0=0xb0;
ET0=1;//promise interrupt
TR0=1;//start T0
EA=1;
}
//==============================================
void int0_init()
{
IT0=1;EX0=1;EA=1;
}
//===============================================
void pwm_init()
{
cmod=0x82; //PCA在空闲模式下停止PCA计数器工作,PCA时钟源为内部时钟(PSC)的1/2溢出,禁止PCA计数器溢出中断
ccon=0x00; //禁止PCA计数器工作,清除中断标志和计数器溢出标志
cl=0x00;ch=0x00; //计数器高低位清0
ccapm1=0x42;//设置模块1为PWM脉冲在P35口输出
PWM_ON_OFF=OFF;//先关闭PWM-输出为0,写入0x00就可开PWM输出
PWM_DISENABLE;
epca_lvd=1;EA=1;cr=1;//开PCA中断-开总中断-PCA计数器打开
}
//================================================
void adc_init()
{
p1m0|=0xa8;p1m1|=0xa8;//设置P17-P15-P13为开漏即AD转换模式,对应电流-欠压-转把的测量
adc_data=0x00;
adc_contr=ADC_POWER;
delay_ms(10);//首次开AD电源要延时1MS左右
}
//================================================
void delay_ms(int t)
{
int i,j;
for(i=0;i<t;i++)for(j=0;j<250;j++);
}
//================================================
void delay_us(int t)
{
int i;
for(i=0;i<t;i++);
}
//================================================
u8 get_ad_data(u8 ch)
{
u8 temp;
adc_data=0;
adc_contr=ADC_POWER|ADC_SPEED|ADC_START|ch;
delay_us(5);
while(!(adc_contr&ADC_FLAG));
temp=adc_data;
adc_contr&=(~ADC_START);
adc_contr&=(~ADC_FLAG);
return temp;
}
//================================================
void time0()interrupt 1
{
TH0=0x3c;TL0=0xb0;//50ms 11.0592MHz
//---------以下为重负载低速计时----------------
if(speed_timer_flag==1)overload_count++;
else overload_count=0;
//---------以下为LED处理-----------------------
if(led_out_flag)
{
if(led_a==1)
{
timer0_a++;
if(timer0_a>=led_time)
{
led_out=~led_out;timer0_b++;timer0_a=0;
if(timer0_b>=led_count){timer0_b=0;led_a=0;}
}
}
else //灭灯间隔
{
led_out=1;timer0_c++;
if(timer0_c>=20){timer0_c=0;led_a=1;}
}
}
else{timer0_a=0;timer0_b=0;timer0_c=0;}
}
//=====================================================
void int0()interrupt 0
{
pwm_out_off();
led(7);
}
//======================================================
void pwm_out_on(u8 pd,u8 hd)
{
PWM_DATA=pd; //写入经AD转换后的转把PWM数据
PWM_ON_OFF=ON;//PWM输出
phase3_out(hd);
}
//=======================================================
void pwm_out_off()
{
PWM_ON_OFF=OFF;
all_bridge_off();
}
//=======================================================
u8 get_hall_data()
{
u8 temp,hall_fault_flag;
u8 i,j;
i=P1&0x07;delay_us(5);j=P1&0X07; //2次读入霍尔数据
if(i-j){hall_fault_flag=1;}
else
{
temp=j;
//----------霍尔120度,查是否全1和全0-----------------
if((temp==0x07)||(temp==0x00)){hall_fault_flag=1;}
else {hall_fault_flag=0;hall_data_now=temp;}
}
return hall_fault_flag;
}
//=========================输出相序============================
//AL,BL,CL,AH,BH,CH===P2.5~P2.0 P2.6==ABS P2.7==LED
//入口:霍尔数据 hall_data
//出口:输出节拍:a+b-,c+b-,c+a-,b+a-,b+c-,a+c-
//对应hall_data: 101 001 011 010 110 100
//==============================================================
void phase3_out(u8 hd)
{
switch(hd)
{
case 1: {AL=0;BL=1;CL=0;AH=0;BH=0;CH=1;} break;//c+b-
case 2: {AL=1;BL=0;CL=0;AH=0;BH=1;CH=0;} break;//b+a-
case 3: {AL=1;BL=0;CL=0;AH=0;BH=0;CH=1;} break;//c+a-
case 4: {AL=0;BL=0;CL=1;AH=1;BH=0;CH=0;} break;//a+c-
case 5: {AL=0;BL=1;CL=0;AH=1;BH=0;CH=0;} break;//a+b-
case 6: {AL=0;BL=0;CL=1;AH=0;BH=1;CH=0;} break;//b+c-
}
}
//===================================================
void all_bridge_off()
{
AH=0;BH=0;CH=0;AL=0;BL=0;CL=0;
}
//===================================================
void up_bridge_on()
{
AH=1;BH=1;CH=1;
}
//===================================================
void down_bridge_on()
{
AL=1;BL=1;CL=1;
}
//==============电机速度测量函数 ====================
u8 speed_detect(u8 hdn)
{
u8 speed_lower_flag=0;
u8 i=0,result=0;
if(speed_a<6)
{
hall_data_table[speed_a]=hdn;
speed_a++;
}
else if(speed_a==6)
{
speed_a=0;
for(i=0;i<6;i++){result=(result+hall_data_table);}
if(result==21)//转子15对极,转一圈霍尔输出15个周期,数字21为一个周期的三相霍尔数据和
{
result=0;
speed_count++;//霍尔周期数累加
speed_timer_flag=1; //50ms计时开始标志置1
if(overload_count==200)//2S延时到
{
overload_count=0;
speed_timer_flag=0;
//转子15对极,转一圈霍尔输出15个周期,600r/min即10圈/s,即150周期/s,
//实际转速折算的周期值比程序中的周期值要大,可能其他程序有消耗时间
if(speed_count<350) //2s300个周期,电机750r/min折算到程序没有187T/s,可能只有150T/s
{
speed_lower_flag=1;
speed_count=0;
}
else{speed_lower_flag=0;}
}
}
}
return speed_lower_flag;
}
//====================================================================
//函数:平均电流检测限流函数
//入口:LM358第7脚的电流经AD转换后的值
//出口:供PWM调整占空比值
u8 current_detect(u8 ch7)
{
u8 temp,over_current_flag=0;
temp=get_ad_data(ch7);
if(temp>40){over_current_flag=1;}//358放大倍数约4倍,康铜20m欧 ,10A的电流temp值40
else {over_current_flag=0;}
return over_current_flag;
}
//======================================================================
u8 mosfet_check(u8 ch7)
{
u8 mosfet_check_flag=0;
//-------------------上桥测试-----------------------
down_bridge_on();
PWM_DATA=0x00; //全开占空比
PWM_ON_OFF=ON;
if(get_ad_data(ch7)>2){mosfet_check_flag=1;}//上桥MOS管有故障
else{mosfet_check_flag=0;}
//------------关输出延时防上下桥短路 ---------------
pwm_out_off();
delay_us(5);
//-------------------下桥测试-----------------------
up_bridge_on();
PWM_DATA=0x00;
PWM_ON_OFF=ON;
if(get_ad_data(ch7)>2){mosfet_check_flag=1;}//上桥MOS管有故障
else{mosfet_check_flag=0;}
pwm_out_off();
return mosfet_check_flag;
}
//=========================把手AD值检测=================================
void handle_service(u8 ch3)
{
u8 i=0,j=0;
u8 max_data=20;
u8 min_data=255;
u8 temp=0;
temp=get_ad_data(ch3);
if((temp<40)||(temp>200)){led(2);PWM_DISENABLE;}//0.8v以下或3.8v以上,有故障
else
{
if((temp>40)&&(temp<45)){led(1);PWM_DISENABLE;}//待机
else if(temp>45){PWM_ENABLE;led(8);}//运行
pwm_data=pwm_out_table[temp];
while(current_detect(7)==ERROR){led(3);pwm_out_off();}
while(get_hall_data()==ERROR){led(6);pwm_out_off();}
pwm_out_on(pwm_data,hall_data_now);
if(temp>170)//3V对应AD值150,3.9V对应AD值200
{
if(hall_data_now!=hall_data)
{
hall_data=hall_data_now;
if(speed_detect(hall_data)==ERROR){while(1){led(5);pwm_out_off();}}
}
}
}
}
//=========================led函数==============================
// 闪1次=待机
// 闪2次=转把未归0或AD值不正常
// 闪3次=358放大电路检测到电流参数不对或有开路情况
// 闪4次=输出MOS有故障
// 闪5次=电机堵转保护后停止
// 闪6次=电机相序不对或霍尔损坏
// 闪7次=358比较器检测到电流过大保护(外部中断)
// 快闪=工作
void led(u8 led_number)
{
switch(led_number)
{
case 0:{led_out_flag=0;led_count=0;led_time=0;}break;
case 1:{led_out_flag=1;led_count=2;led_time=4;}break;
case 2:{led_out_flag=1;led_count=4;led_time=4;}break;
case 3:{led_out_flag=1;led_count=6;led_time=4;}break;
case 4:{led_out_flag=1;led_count=8;led_time=4;}break;
case 5:{led_out_flag=1;led_count=10;led_time=20;}break;
case 6:{led_out_flag=1;led_count=12;led_time=4;}break;
case 7:{led_out_flag=1;led_count=14;led_time=4;}break;
case 8:{led_out_flag=1;led_count=50000;led_time=1;}break;
}
}
//==========================主函数===============================
void main()
{
system_init();
while(mosfet_check(7)==ERROR){pwm_out_off();led(4);}
while(1)
{
handle_service(3);
show_ADC_result(3);
//show_ADC_result(7);
}
}
一周热门 更多>