牛东 发表于 2015-5-21 14:32:54

stc独立波特率发生器不工作!求助!!!

本帖最后由 牛东 于 2015-5-21 15:04 编辑

正在做一个无刷驱动程序,想到独立波特率发生器作串口通信,程序怎么都不成功,借鉴网上的程序也不行!!(注:用T1串口就可以)

#include<reg51.h>                //包含文件预处理命令

//-------------------------串口独立波特率发生器的特殊寄存器地址定义--------------------------------
sfrAUXR=0x8E;        
sfrBRT=0x9C;   
//================================================
//使用串口独立波特率发生器
void uart_init()
{
        //(注:用T1串口就可以)
        /*SCON=0x50;
        TMOD=(TMOD&0x0f)|0x20;
        TH1=TL1=0xFD; //11.0592M9600
        TR1=1;*/

        //用此段就不行!!
        SCON=0x50;
        AUXR=0x11;
        BRT=0XFD; //11.0592M9600
}
//=============================================                                       
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));
        }
}

饭桶 发表于 2015-5-21 15:18:55

不说STC什么型号的,寄存器地址都不同,怎么判断?

饭桶 发表于 2015-5-21 15:19:28

没开串口中断

饭桶 发表于 2015-5-21 15:20:47

ch是什么?估计楼主把很多程序删除了,这样的态度实在是无语。让别人怎么帮你?

大米饭 发表于 2015-5-21 15:44:02

先给BRT赋值,再AUXR=0x11;启动独立波特率发生器试试
上电延时个几十ms
while(1)               
      {                                                                           
                send_byte(get_ad_data(ch));
                //此处来点延时啦,你想把串口助手给累死啊
      }
一直发送数据,也稍微加个延时啊,有点时候是你单片机发太快了,串口助手显示不出来而已

牛东 发表于 2015-5-21 16:36:43

饭桶 发表于 2015-5-21 15:18
不说STC什么型号的,寄存器地址都不同,怎么判断?

STC12C5410ad{:handshake:}

牛东 发表于 2015-5-21 16:38:23

饭桶 发表于 2015-5-21 15:20
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转换要用到的特殊寄存器地址定义----------------------------------------
sfradc_contr=0xc5;             //定义AD转换控制寄存器地址   
sfradc_data=0xc6;            //定义AD转换结果寄存器地址
sfrp1m0=0x91;                  //带有8路AD的P1口模式选择寄存器0定义地址,本程序中将带有AD转换的口设置成开漏
sfrp1m1=0x92;                  //带有8路AD的P1口模式选择寄存器1定义地址,本程序中将带有AD转换的口设置成开漏
//-------------------------PWM=p35输出要用到的特殊寄存器地址定义---------------------------------------------
sfrccap1h=0xfb;                //PCA模块1捕捉/比较寄存器高8位
sfrpca_pwm1=0xf3;            //PCA模块1-PWM寄存器
sfrccapm1=0xdb;                //PCA模块1工作模式寄存器
sfrch=0xf9;                  //PCA计数器高8位
sfrcl=0xe9;                  //PCA计数器低8位
sfrccon=0xd8;                  //PCA控制寄存器
sfrcmod=0xd9;                  //PCA工作模式寄存器
//-------------------------串口独立波特率发生器的特殊寄存器地址定义--------------------------------
sfrAUXR=0x8E;                                //独立波特率发生器控制寄存器
sfrBRT=0x9C;                                       //独立波特率发生器寄存器,装初值0xfd是9600;
//------------------------------------------------------------------
typedef   unsigned char      u8;
typedef   unsigned short int   u16;        
typedef   unsigned int         u32;
//-----------------------define PWMregist----------------------------------
#definePWM_ON_OFFpca_pwm1
#defineON    0
#defineOFF   1
#defineERROR 1
#defineOK    0
#definePWM_DATA                  ccap1h
#definePWM_DISENABLE           ccapm1&=0xfd
#definePWM_ENABLE           ccapm1|=0x02
//------------ define ADC opration const for adc_conter----------------
#defineADC_POWER   0x80
#defineADC_FLAG      0x10   
#defineADC_START   0x08   
#defineADC_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;            //防盗检测口

sbitAH=P2^2;
sbitBH=P2^1;
sbitCH=P2^0;
sbitAL=P2^5;
sbitBL=P2^4;
sbitCL=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={0,0,0,0,0,0,};//霍尔数据暂存区

//============================AD转换后PWM对照表==========================================================
u8 code pwm_out_table=//实际一共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~2504v以上视为转把故障 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 2for 8-bit auto reload   
        TH1=TL1=0xFD;//TH=TL=-(FOSC/12/32/BUND) BOUND=9600; FOSC=11.0592M
        TR1=1;*/
        SCON=0x50; //SM1 SM2 = 1 0;REN=1
        AUXR=0x11; //BRTR=1,允许独立波特率发生器运行;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==ABSP2.7==LED
//入口:霍尔数据 hall_data
//出口:输出节拍:a+b-,c+b-,c+a-,b+a-,b+c-,a+c-
//对应hall_data:101001        011       010110100
//==============================================================
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=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;
                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);
        }
}

牛东 发表于 2015-5-21 16:43:39

大米饭 发表于 2015-5-21 15:44
先给BRT赋值,再AUXR=0x11;启动独立波特率发生器试试
上电延时个几十ms
while(1)               


//------------------------------------------------------
//霍尔信号采集定义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转换要用到的特殊寄存器地址定义----------------------------------------
sfradc_contr=0xc5;             //定义AD转换控制寄存器地址   
sfradc_data=0xc6;            //定义AD转换结果寄存器地址
sfrp1m0=0x91;                  //带有8路AD的P1口模式选择寄存器0定义地址,本程序中将带有AD转换的口设置成开漏
sfrp1m1=0x92;                  //带有8路AD的P1口模式选择寄存器1定义地址,本程序中将带有AD转换的口设置成开漏
//-------------------------PWM=p35输出要用到的特殊寄存器地址定义---------------------------------------------
sfrccap1h=0xfb;                //PCA模块1捕捉/比较寄存器高8位
sfrpca_pwm1=0xf3;            //PCA模块1-PWM寄存器
sfrccapm1=0xdb;                //PCA模块1工作模式寄存器
sfrch=0xf9;                  //PCA计数器高8位
sfrcl=0xe9;                  //PCA计数器低8位
sfrccon=0xd8;                  //PCA控制寄存器
sfrcmod=0xd9;                  //PCA工作模式寄存器
//-------------------------串口独立波特率发生器的特殊寄存器地址定义--------------------------------
sfrAUXR=0x8E;                                //独立波特率发生器控制寄存器
sfrBRT=0x9C;                                       //独立波特率发生器寄存器,装初值0xfd是9600;
//------------------------------------------------------------------
typedef   unsigned char      u8;
typedef   unsigned short int   u16;        
typedef   unsigned int         u32;
//-----------------------define PWMregist----------------------------------
#definePWM_ON_OFFpca_pwm1
#defineON    0
#defineOFF   1
#defineERROR 1
#defineOK    0
#definePWM_DATA                  ccap1h
#definePWM_DISENABLE           ccapm1&=0xfd
#definePWM_ENABLE           ccapm1|=0x02
//------------ define ADC opration const for adc_conter----------------
#defineADC_POWER   0x80
#defineADC_FLAG      0x10   
#defineADC_START   0x08   
#defineADC_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;            //防盗检测口

sbitAH=P2^2;
sbitBH=P2^1;
sbitCH=P2^0;
sbitAL=P2^5;
sbitBL=P2^4;
sbitCL=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={0,0,0,0,0,0,};//霍尔数据暂存区

//============================AD转换后PWM对照表==========================================================
u8 code pwm_out_table=//实际一共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~2504v以上视为转把故障 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 2for 8-bit auto reload   
        TH1=TL1=0xFD;//TH=TL=-(FOSC/12/32/BUND) BOUND=9600; FOSC=11.0592M
        TR1=1;*/

        SCON=0x50; //SM1 SM2 = 1 0;REN=1
        BRT=0XFD;//独特波特率发生器定时器(产生波特率9600)
        AUXR=0x11; //BRTR=1,允许独立波特率发生器运行;SIBRS=1,独立波特率作为串口1的波特率发生器,此时定时器1释放
        delay_ms(100);
}
//=============================================                                       
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==ABSP2.7==LED
//入口:霍尔数据 hall_data
//出口:输出节拍:a+b-,c+b-,c+a-,b+a-,b+c-,a+c-
//对应hall_data:101001        011       010110100
//==============================================================
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=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;
                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);
        }
}

页: [1]
查看完整版本: stc独立波特率发生器不工作!求助!!!