智能尋跡小車資料
單片機源程序如下:- /******************************************************************************
- 名稱 :尋跡控制
- cpu : mega16
- 晶振 :內部8M
- ******************************************************************************/
- #include <iom16v.h>
- #include <macros.h>
- #define uchar unsigned char
- #define uint unsigned int
- /******************************************************************************/
- /********************************宏定義***************************************/
- /******************************************************************************/
- #define H595DDR_OUT DDRC |=BIT(0)|BIT(1)|BIT(2)|BIT(3)|BIT(4)|BIT(5)|BIT(6)
- #define H595CTL PORTC //高低高平
- #define H595_SER_H H595CTL |= BIT(PC6) //數據
- #define H595_SER_L H595CTL &= ~BIT(PC6)
- #define H595_RCK_H H595CTL |= BIT(PC5) //副寄存器時鐘
- #define H595_RCK_L H595CTL &= ~BIT(PC5)
- #define H595_SCK_H H595CTL |= BIT(PC4) //主時鐘
- #define H595_SCK_L H595CTL &= ~BIT(PC4)
- #define H595DDR_OUT1 DDRD |=BIT(0)|BIT(1)|BIT(2)
- #define H595CTL1 PORTD //高低高平
- #define H595_SER1_H H595CTL1 |= BIT(PD0) //數據
- #define H595_SER1_L H595CTL1 &= ~BIT(PD0)
- #define H595_RCK1_H H595CTL1 |= BIT(PD1) //副寄存器時鐘
- #define H595_RCK1_L H595CTL1 &= ~BIT(PD1)
- #define H595_SCK1_H H595CTL1 |= BIT(PD2) //主時鐘
- #define H595_SCK1_L H595CTL1 &= ~BIT(PD2)
- #define SEG_1_H H595CTL |= BIT(PC0)//數碼管四個位選端
- #define SEG_1_L H595CTL &= ~BIT(PC0)
- #define SEG_2_H H595CTL |= BIT(PC1)
- #define SEG_2_L H595CTL &= ~BIT(PC1)
- #define SEG_3_H H595CTL |= BIT(PC2)
- #define SEG_3_L H595CTL &= ~BIT(PC2)
- #define SEG_4_H H595CTL |= BIT(PC3)
- #define SEG_4_L H595CTL &= ~BIT(PC3)
- #define BACK1_ON PORTB |= BIT(PD3) //前后//轉向檔瓶刂?
- #define BACK1_OFF PORTB &= ~BIT(PD3)
- #define BACK2_ON PORTB |= BIT(PD4)
- #define BACK2_OFF PORTB &= ~BIT(PD4)
- /******************************************************************************/
- /**********************************end*****************************************/
- /******************************************************************************/
- uint count,ppp,count1,voltage;
- uchar angle_flag1,angle_flag2=0;
- uchar anglel,angleh;
- uint i=0;
- uchar sudu=0x40;
- uchar AD_num1,AD_num=0;
- static uchar black_flag;
- static uchar online;
- uint AD_get[8]={0,0,0,0,0,0,0,0};
- uint AD_min[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
- uint AD_max[8]={0,0,0,0,0,0,0,0};
- uint AD_read[8]={0,0,0,0,0,0,0,0};
- static uchar weiseg[4] = {0xfe,0xfd,0xfb,0xf7};
- static uchar state[]={4,12,8,10,26,58,18,48,32,33,1,65,64,128};
- static uchar shushow[11]={
- 0xFA,/*0*/
- 0x60,/*1*/
- 0xDC,/*2*/
- 0xF4,/*3*/
- 0x66,/*4*/
- 0xB6,/*5*/
- 0xBE,/*6*/
- 0xE0,/*7*/
- 0xFE,/*8*/
- 0xF6,/*9*/
- 0x00
- };
- static uchar taple[] = {
- 0xff,
- 0xe7,
- 0xc3,
- 0x81,
- 0x00,
- 0x18,
- 0x3c,
- 0x7e,
- 0xff,
- 0xaa,
- 0x55
- };
- static uint smg[11] = {
- 1,
- 12,
- 123,
- 1234,
- 2345,
- 3456,
- 4567,
- 5678,
- 6789,
- 9123,
- 3210
- };
- void AD_control();
- void angle_control();
- void set_angle(uchar agh,uchar agl);
- void display(uint shuzhi);
- void delay1(int k) ;
- void set595(uchar s2);
- void led_line(uchar s2);
- /*******************************************************************************/
- //////////////////////////////中斷初始化函數/////////////////////////////////////
- /*******************************************************************************/
- /******************************************************************************
- 端口初始化函數
- ******************************************************************************/
- void port_init(void)
- {
- DDRA = 0x00;
- PORTB = 0x00;
- DDRB = 0xff;
- PORTC = 0x0F;
- DDRC = 0x7F;
- PORTD = 0x00;
- DDRD = 0xff;
- H595DDR_OUT ;
- H595DDR_OUT1;
- }
- /******************************************************************************
- AD初始化函數
- ******************************************************************************/
- void adc_init(void)
- {
- ADCSRA = 0x00; //禁止AD轉換
- ADMUX = 0x60;
- SFIOR |= 0x00;
- ACSR = 0x80; //禁止模擬比較器
- ADCSRA = 0xEE;
- }
- /**********************定時T1初始化******************************
- 模式:8位相位修正PWM模式
- 舵角控制: OCR1AL=0XCA時,左最大,0XD0時,中間位置,0XD7時右轉最大
- 系統時鐘:內部8MHZ,經256分頻得61.275HZPWM頻率
-
- ****************************************************************/
- //定時T1初始化
- void timer1_init(void)
- {
- TCCR1B = 0x00;//停止定時器
- TIMSK |= 0x18;//中斷允許
- TCNT1H = 0x00;
- TCNT1L = 0x00;//初始值
- OCR1AH = 0x00;
- OCR1AL = 0xC9;//匹配A值(C8-D0-DA)
- OCR1BH = 0x00;
- OCR1BL = 0x09;//匹配B值
- TCCR1A = 0xf1;
- // TCCR1B = 0x04;//啟動定時器
- TCCR1B = 0x04;//啟動定時器
- }
- /******************************************************************************
- 串口初始化函數
- ******************************************************************************/
- void uart0_init(void)
- {
- UCSRB = 0x00; //disable while setting baud rate
- UCSRA = 0x00;
- UCSRC = BIT(URSEL) | 0x06;
- UBRRL = 0x67;
- UBRRH = 0x00;//set baud rate hi
- UCSRB = 0x98;
- }
- /**********************************END****************************************/
- /*****************************************************************************/
- ///////////////////////////////中斷處理函數////////////////////////////////////
- /*****************************************************************************/
- void uart0_tx_isr( char x)
- {
- while(!(UCSRA&0x20));
- UDR=x;
- }
- unsigned int adc_calc(void)
- {
- //計算實際電壓
- unsigned long value=0;
- value = ADCL>>6; //首先讀低位
- value|=(int)ADCH << 2; //然后讀高位
- voltage = value;
- return voltage;
- }
- /*************************************************
- 中斷接受,同時發送接受到的內容
- **************************************************/
- #pragma interrupt_handler uart0_rx_isr:12
- void uart0_rx_isr(void)
- {
- unsigned char x;
- CLI();
- x=UDR;
- uart0_tx_isr(x);
- SEI();
- }
- #pragma interrupt_handler adc_isr:15
- void adc_isr(void)//轉換完成后中斷處理
- {
- uchar back_flag;
- AD_num++;
- ADMUX++;
- if(AD_num>7)
- {
- AD_num = 0;
- ADMUX = 0x60;
- }
- voltage=adc_calc();
- AD_get[AD_num1]=voltage;
-
- /*********************************AD轉換值處理*****************************************/
-
- /* AD_min[AD_num1]=(AD_get[AD_num1]<AD_min[AD_num1]) ? AD_min[AD_num1]:AD_get[AD_num1];
- AD_max[AD_num1]=(AD_get[AD_num1]>AD_max[AD_num1]) ? AD_max[AD_num1]:AD_get[AD_num1];
- AD_read[AD_num1]= (AD_min[AD_num1]+ AD_max[AD_num1])*3/4 ;
- if(AD_get[AD_num1]>AD_read[AD_num1])
- {
- back_flag|=BIT(i);
- black_flag=back_flag;
- } */
- /********************************此部分有待證實*****************************************/
- AD_num1++;
- if(AD_num1>7)
- AD_num1=0;
- }
- /**************************************************/
- /////////////////定時器T1匹配中斷A服務程序/////////
- /**************************************************/
- #pragma interrupt_handler timer1_compa_isr:7
- void timer1_compa_isr(void)
- {
- CLI();
- if(angle_flag1==1)
- {
- angle_flag1=0;
- OCR1AH = angleh;
- OCR1AL = anglel;
- }
- SEI();
- }
- //定時器T1匹配中斷B服務程序
- #pragma interrupt_handler timer1_compb_isr:8
- void timer1_compb_isr(void)
- {
- CLI();
- if(angle_flag2==1)
- {
- angle_flag2=0;
- OCR1BH = 0x00;
- OCR1BL = sudu;
- }
- SEI();
- }
- /******************************************************************************/
- ///////////////////////////time delay funtion///////////////////////////////////
- /******************************************************************************/
- void delay1(int k) //延時
- {
- int i;
- for(i=0;i<k;i++);
- }
-
- /******************************************************************************/
- /*****************************595掃描流水燈函數********************************/
- /******************************************************************************/
- void set595(uchar s2)
- {
- uchar mid,j = 0;
- CLI();
- for (j=0;j<8;j++)
- {
- mid=s2&0x01;
- H595_SCK_L ;
- if (mid == 0)
- H595_SER_L ;
- else
- H595_SER_H;
- NOP();
- H595_SCK_H;
- NOP();
- s2=s2>>1;
- }
- H595_RCK_L ;
- NOP();
- H595_RCK_H;
- SEI();
-
- }
-
- void led_line(uchar s2)
- {
- uchar mid,j=0;
- CLI();
- for (j=0;j<8;j++)
- {
- mid=s2&0x01;
- H595_SCK1_L ;
- if (mid==0)
- H595_SER1_L ;
- else
- H595_SER1_H;
- NOP();
- H595_SCK1_H;
- NOP();
- s2=s2>>1;
- }
- H595_RCK1_L ;
- NOP();
- H595_RCK1_H;
- SEI();
- }
-
-
- void display(uint shuzhi)
- {
- uchar ge,shi,bai,qian;
- if(shuzhi > 999)
- {
- ge=shuzhi%10;
- shi=shuzhi%100/10;
- bai=shuzhi%1000/100;
- qian=shuzhi/1000;
- }
- else if(shuzhi>99)
- {
- ge=shuzhi%10;
- shi=shuzhi%100/10;
- bai=shuzhi/100;
- qian=10;
- }
- else if(shuzhi>9)
- {
- ge = shuzhi%10;
- shi = shuzhi/10;
- bai = 10;
- qian = 10;
- }
- else
- {
- ge = shuzhi;
- shi = 10;
- bai = 10;
- qian = 10;
- }
- set595(shushow[ge]);
- SEG_4_L;
- delay1(200);
- SEG_4_H;
- set595(shushow[shi]);
- SEG_3_L;
- delay1(200);
- SEG_3_H;
-
- set595(shushow[bai]);
- SEG_2_L;
- delay1(200);
- SEG_2_H;
-
- set595(shushow[qian]);
- SEG_1_L;
- delay1(200);
- SEG_1_H;
- }
-
- /******************************************************************************/
- /**********************************END*****************************************/
- /******************************************************************************/
- /********************************角度,速度實時處理函數************************/
- void set_angle(uchar agh,uchar agl)
- {
- angle_flag1=1;
- angleh=agh;
- anglel=agl;
-
- }
- void set_sudu(uchar sd)
- {
- angle_flag2=1;
- sudu=sd;
- }
- /************************************end***************************************/
-
-
-
-
- /*********************坡道處理函數,有待實踐證實********************************/
- void set_podao()
- {
- uint ii,iii;
- if(i<100)//上坡
- AD_control();
- else
- if(i>100)//下坡趨勢//傍晚100快速50
- {
- for(ii=0;ii<6000;ii++ )
- {
- AD_control();
- switch(black_flag)
- {
- case 4: set_angle(0x00,0xc8);set_sudu(0xca);BACK2_ON ;break; //2
- case 6: set_angle(0x00,0xca);set_sudu(0xca);BACK2_ON ;break; //12
- case 2 : set_angle(0x00,0xcb);set_sudu(0x9a);BACK2_ON ;break; //1
- case 10: set_angle(0x00,0xcc);set_sudu(0x9a);BACK2_ON ;break; //13
- case 8 : set_angle(0x00,0xcd);set_sudu(0x9a);break; //3
- case 24: set_angle(0x00,0xce);set_sudu(0x9a);break; //34
- case 56: set_angle(0x00,0xcf);set_sudu(0x90);break; //345
- case 16: set_angle(0x00,0xcf);set_sudu(0x90);break; //4
- case 48: set_angle(0x00,0xd0);set_sudu(0x91);break; //45
- case 32: set_angle(0x00,0xd0);set_sudu(0x91);break; //5
- case 96: set_angle(0x00,0xd1);set_sudu(0x91);break; //56
- case 64: set_angle(0x00,0xd2);set_sudu(0x91);break; //6
- case 65: set_angle(0x00,0xd4);set_sudu(0x91);break; //06
- case 1: set_angle(0x00,0xd5);set_sudu(0x91);;BACK1_ON ;break; //0
- case 129: set_angle(0x00,0xd7);set_sudu(0x91);;BACK1_ON ;break; //07
- case 128: set_angle(0x00,0xd9);set_sudu(0xc1);;BACK1_ON ;break; //7
- // default:i++;set_angle(0x00,0xd0);break;
- default:set_angle(0x00,0xd0);break;
- }
- }
- i=0;
- }
- }
- /************************************end***************************************/
-
-
-
-
- /******************************************************************************/
- ///
- //// ///
- /// ///////////////////
- /// ///
- ///
- //////// /////////////////////
- ///
- // ///
- /// /// ///
- ////// /////////////////////
- ////
- /******************************************************************************/
- void Online(uchar sd)
- {
- online++;
- if(online==10)
- {
- online = 0;
- set_sudu(sd);
- }
- set_sudu(0x90);
- }
- void angle_control()
- {
-
- BACK1_OFF ; //轉向燈
- BACK2_OFF ;
- switch(black_flag)
- {
- case 4: set_angle(0x00,0xc8);set_sudu(0xaa);BACK2_ON ;break; //2
- case 6: set_angle(0x00,0xcb);set_sudu(0x41);BACK2_ON ;break; //12
- case 2 : set_angle(0x00,0xcd);set_sudu(0x20);BACK2_ON ;break; //1
- case 10: set_angle(0x00,0xce);set_sudu(0x15);break; //13
- case 8 : set_angle(0x00,0xcd);set_sudu(0x10);break; //3
- case 24: set_angle(0x00,0xce);set_sudu(0x02);break; //34
- case 56: set_angle(0x00,0xcf);set_sudu(0x01);break; //345
- case 16: set_angle(0x00,0xcf);set_sudu(0x01);break; //4
- case 48: set_angle(0x00,0xd0);set_sudu(0x01);break; //45
- case 32: set_angle(0x00,0xd1);set_sudu(0x01);break; //5
- case 96: set_angle(0x00,0xd1);set_sudu(0x02);break; //56
- case 64: set_angle(0x00,0xd2);set_sudu(0x10);break; //6
- case 65: set_angle(0x00,0xd4);set_sudu(0x15);break; //06
- case 1: set_angle(0x00,0xd5);set_sudu(0x20);BACK1_ON;break; //0
- case 129: set_angle(0x00,0xd7);set_sudu(0x41);BACK1_ON;break; //07
- case 128: set_angle(0x00,0xd9);set_sudu(0xa1);BACK1_ON;break; //7
- // case 0:set_sudu(0x5a);BACK1_ON ;break; //7
- default:i++;set_angle(0x00,0xd0);set_podao();break;
- }
-
- }
- void AD_control()
- {
- uchar i;
- uchar back_flag=0;
- for(i=0;i<8;i++)
- {
- AD_min[i]=(AD_get[i]<AD_min[i]) ? AD_min[i]:AD_get[i];
- AD_max[i]=(AD_get[i]>AD_max[i]) ? AD_max[i]:AD_get[i];
- AD_read[i]= (AD_min[i]+ AD_max[i])*7/10 ;
- if(AD_get[i]>AD_read[i])
- {
- back_flag|=BIT(i);
- black_flag=back_flag;
- }
- }
- }
- void init_devices(void)
- {
- CLI(); //禁止所有中斷
- MCUCR = 0x00;
- MCUCSR = 0x80;//禁止JTAG
- GICR = 0x00;
- port_init();
- adc_init();
- // uart0_init();
- timer1_init();
- // OSCCAL=0Xff;// 內部8m時鐘校正
- SEI();//開全局中斷
- }
-
-
-
- /******************************************************************************/
- /********************************MAIN FUNTION**********************************/
- /******************************************************************************/
- void main()
- {
- uint Count,Count1;
- uchar Count2;
- init_devices();
- while(1)
- {
- Count++;
- if(Count>200)
- {
- Count=0;
- Count1++;
- if(Count1>11)
- Count1=0;
- Count2=Count1;
- led_line(taple[Count2]);
- }
- //led_line(Count2);
- display(8888);
- //display(black_flag);
- AD_control();
- angle_control();
- }
- }
復制代碼
PCB文件下載(有錯誤 僅供參考 求大神指導):
資料.7z
(73.04 KB, 下載次數: 6)
2023-12-15 02:12 上傳
點擊文件名下載附件
|