51單片機驅動PS2搖桿1602顯示程序(1602用6根線驅動- /********************************************************
- 功 能:51單片機通過PS2搖桿模塊驅動4個LED
- 并用1602顯示
- (1602使用6根線驅動)
- 單片機:STC12C2052AD
- 晶 振:12M
- 注 釋:搖桿的x軸接單片機P10.搖桿的Y軸接單片機P11.
- Z軸接P17
- 作 者:蘇義江改編自網絡
- 時 間:2016-10-12
- *******************************************************/
- #include<stc12c2052ad.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- //#define TINER_HIGH 0XFF//24M
- //#define TINE_LOW 0XD8
- #define TINER_HIGH 0XFf//12M 100us
- #define TINE_LOW 0X9c
- #define ADC_POWER 0x80 //定義ADC電源常量
- #define ADC_FLAG 0x10 //定義ADC轉換結束標志位
- #define ADC_START 0x08 //定義ADC轉換開始控制位
- #define ADC_SPEEDLL 0x00 //1080個時鐘轉換一次
- #define ADC_SPEEDL 0x20 //810個時鐘轉換一次
- #define ADC_SPEEDH 0x40 //540個時鐘轉換一次
- #define ADC_SPEEDHH 0x60 //270個時鐘轉換一次
- sbit led_red =P1^6;
- sbit led_green =P1^5;
- sbit led_blue =P1^4;
- sbit led_yellow=P1^3;
- sbit z_zhou =P1^7;//Z軸
- uchar red=0x00,green=0x00,blue=0x00,yellow=0x00;
- uchar counter=0;
- typedef struct
- {
- char x;
- char y;
- char drift;
- }pos;
- pos rocker;
- void delay(uint t)
- {
- uint y,i; //定義變量
- for(y=t;t>0;t--) //如果t大于0,t減1(外層循環)
- for(i=600;i>0;i--); //i等于600,如果i大于0,i減1
- }
- ////////STC12C5608AD轉換定義在哪個IO口進行并轉換//////////////
- uchar Read5608AD (uchar CHA)
- {
- uchar AD_FIN=0; //存儲A/D轉換標志;若在函數外定義此變量則不能得到連續變化的模擬量的顯示
- /////////以下為ADC初始化程序////////////
- CHA &= 0x03;
- //選擇ADC的8個接口中的一個(0000 0011 清0高6位)
- ADC_CONTR = ADC_SPEEDHH; //ADC轉換的速度(0XX0 0000 其中XX控制速度,請根據數據手冊設置)
- _nop_();
- ADC_CONTR |= CHA; //選擇A/D當前通道
- _nop_();
- ADC_CONTR |= ADC_POWER; //啟動A/D電源(1000 0000)
- delay(1); //使輸入電壓達到穩定(1ms即可?
- /////以下為ADC執行程序///////////////////
- ADC_CONTR |= ADC_START; //啟動A/D轉換(0000 1000 令ADCS = 1)
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- while (AD_FIN ==0) //等待A/D轉換結束
- {
- AD_FIN = (ADC_CONTR & ADC_FLAG); //0001 0000測試A/D轉換結束否
- }
- ADC_CONTR &= 0xE7; //1111 0111 清ADC_FLAG位, 關閉A/D轉換,
- return (ADC_DATA); //返回A/D轉換結果(8位)
- }
- /*
- ///////////STC12C2052AD轉換//////////////
- uchar Read2052AD (uchar CHA)
- {
- uchar AD_FIN=0; //存儲A/D轉換標志;若在函數外定義此變量則不能得到連續變化的模擬量的顯示
- //////以下為ADC初始化程序/////////////////
- CHA &= 0x07; //選擇ADC的8個接口中的一個(0000 0111 清0高5位)
- ADC_CONTR = 0x60; //ADC轉換的速度(0XX0 0000 其中XX控制速度,請根據數據手冊設置)
- _nop_();_nop_();_nop_();
- ADC_CONTR |= CHA; //選擇A/D當前通道
- _nop_();_nop_();_nop_();
- ADC_CONTR |= 0x80; //啟動A/D電源
- delay(2); //使輸入電壓達到穩定(1ms即可?
- //////////以下為ADC執行程序////////////////////
- ADC_CONTR |= 0x08; //啟動A/D轉換(0000 1000 令ADCS = 1)
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- while (AD_FIN ==0)
- { //等待A/D轉換結束
- AD_FIN = (ADC_CONTR & 0x10); //0001 0000測試A/D轉換結束否
- }
- ADC_CONTR &= 0xE7; //1111 0111 清ADC_FLAG位, 關閉A/D轉換,
- return (ADC_DATA); //返回A/D轉換結果(8位)
- }
- */
- pos rocker_read(int drift)
- {
- pos buffer;
- buffer.x=128-Read5608AD (1);
- buffer.y=128-Read5608AD (0);
- buffer.drift=drift;
- return (buffer);
- }
- void timer0_init()
- {
- TMOD=0X01;
- TH0=TINER_HIGH ;
- TL0=TINE_LOW;
- ET0=1;
- TR0=1;
- EA=1;
- }
- void timer0_irpt() interrupt 1
- {
- TH0=TINER_HIGH ;
- TL0=TINE_LOW;
- counter++;
- if(counter<red) led_red=0; else led_red=1;
- if(counter<green) led_green=0; else led_green=1;
- if(counter<blue) led_blue=0; else led_blue=1;
- if(counter<yellow) led_yellow=0; else led_yellow=1;
- }
- //6根線驅動LCD1602接口定義
- #define LCD_DB P2 // - - P2 = DB4~DB7
- sbit LCD_RS=P2^2; // - - p2.2 = RS
- //sbit LCD_RW=P0^6; // - - p2.1 = RW 接地
- sbit LCD_E=P2^3; // - - p2.3 = E
- // - - 定義子程序函數
- void LCD_init(void); // - - 初始化LCD1602函數
- void LCD_write_H4bit_command(uchar dat);
- void LCD_write_L4bit_command(uchar dat);
- void LCD_write_4bit_command(uchar command); // - - 向LCD1602寫指令函數
- void LCD_write_4bit_data(uchar dat); // - - 向LCD1602寫數據函數
- void LCD_set_xy(uchar x,uchar y); // - - 設置LCD1602顯示位置 X(0-16),y(1-2)
- void LCD_disp_char(uchar x,uchar y,uchar dat); // - - 在LCD1602上顯示一個字符
- void LCD_disp_string(uchar X,uchar Y,uchar *s); // - - 在LCD1602上顯示一個字符串
- //void LCD_check_busy(void);//檢查忙函數。我沒用到此函數,因為通過率極低。
- void LCD_delay_10us(uint n); // - - 10微秒的延時子程序
- void LCD_delay_50us(uint n); // - - 50微秒的延時子程序
- void LCD_delay_10us(uint n) // - - 10微秒的延時子程序
- {
- uint i,j;
- for(i=n*10;i>0;i--) // - - 晶振及單片機修改設置
- for(j=2;j>0;j--);
- }
- void LCD_delay_50us(uint n) // - - 50微秒的延時子程序
- {
- uint i,j;
- for(i=n*10;i>0;i--) // - - 晶振及單片機修改設置
- for(j=22;j>0;j--);
- }
- // - - 初始化LCD1602
- void LCD_init(void)
- {
- LCD_delay_50us(50);
- LCD_RS=0; // - - 指令
- // LCD_RW=0; // - - 寫入
- LCD_E=0; // - - 使能
- LCD_write_L4bit_command(0x03); // - - 設置4位格式,2行,5x7
- LCD_delay_50us(20);
- LCD_write_L4bit_command(0x03); // - - 設置4位格式,2行,5x7
- LCD_delay_50us(20);
- LCD_write_L4bit_command(0x02); // - - 設置4位格式,2行,5x7
- LCD_delay_50us(2);
- LCD_write_4bit_command(0x28); // - - 設置4位格式,2行,5x7
- LCD_delay_10us(10);
- LCD_write_4bit_command(0x28); // - - 設置4位格式,2行,5x7
- LCD_delay_10us(10);
- LCD_write_4bit_command(0x0c); // - - 整體顯示,關光標,不閃爍
- LCD_delay_10us(10);
- LCD_write_4bit_command(0x06); // - - 設定輸入方式,增量不移位
- LCD_delay_10us(10);
- LCD_write_4bit_command(0x01); // - - 清除屏幕顯示
- LCD_delay_50us(40);
- }
- //********************************
- // - - 向LCD1602寫指令
- void LCD_write_4bit_command(uchar dat)
- {
- LCD_delay_10us(50);
- LCD_RS=0; // - - 指令
- // LCD_RW=0; // - - 寫入
- LCD_write_H4bit_command(dat);
- LCD_write_L4bit_command(dat);
- }
- // - - 向LCD1602寫高四位指令
- void LCD_write_H4bit_command(uchar dat)
- {
- LCD_delay_10us(250);
- LCD_DB=(LCD_DB&0x0F)|(dat&0xF0);
- LCD_delay_10us(50);
- LCD_E=1; // - - 允許
- LCD_delay_10us(250);
- LCD_E=0;
- }
- // - - 向LCD1602寫低四位指令
- void LCD_write_L4bit_command(uchar dat)
- {
- dat<<=4;
- LCD_delay_10us(50);
- LCD_DB=(LCD_DB&0x0F)|(dat&0xF0);
- LCD_delay_10us(50);
- LCD_E=1; // - - 允許
- LCD_delay_10us(250);
- LCD_E=0;
- }
- // - - 向LCD1602寫數據
- void LCD_write_4bit_data(uchar dat)
- {
- LCD_delay_10us(50);
- LCD_RS=1; // - - 數據
- // LCD_RW=0; // - - 寫入
- LCD_write_H4bit_command(dat);
- LCD_write_L4bit_command(dat);
- }
- // - - 設置顯示位置
- void LCD_set_xy(uchar x,uchar y)
- {
- uchar address;
- if(y==1)
- {
- address=0x80+x; // - - 第一行位置
- }
- else
- {
- address=0xc0+x; // - - 第二行位置
- }
- LCD_delay_10us(50);
- LCD_write_4bit_command(address);
- }
- // - - 顯示一個字符函數
- void LCD_disp_char(uchar x,uchar y,uchar dat)
- // - - LCD_disp_char(0,1,0x38); // - - 顯示8
- {
- LCD_set_xy(x,y);
- LCD_delay_10us(5);
- LCD_write_4bit_data(dat);
- }
- // - - 顯示一個字符串函數
- void LCD_disp_string(uchar x,uchar y,uchar *s)
- {
- LCD_set_xy(x,y);
- LCD_delay_10us(5);
- while(*s!='\0')
- {
- LCD_write_4bit_data(*s);
- s++;
- }
- }
- void display(uint num )//顯示數字
- {
- uchar qian,bai,shi,ge;
- qian=num/1000;
- bai=num%1000/100;
- shi=num%100/10;
- ge=num%10;
- LCD_set_xy(3,0);
- LCD_write_4bit_data(qian+0x30);
- LCD_write_4bit_data(bai+0x30);
- LCD_write_4bit_data(shi+0x30);
- LCD_write_4bit_data(ge+0x30);
- }
- void display1(uint num )//顯示數字
- {
- uchar qian,bai,shi,ge;
- qian=num/1000;
- bai=num%1000/100;
- shi=num%100/10;
- ge=num%10;
- LCD_set_xy(11,0);
- LCD_write_4bit_data(qian+0x30);
- LCD_write_4bit_data(bai+0x30);
- LCD_write_4bit_data(shi+0x30);
- LCD_write_4bit_data(ge+0x30);
- }
- void main()
- {
- LCD_init();
- timer0_init();
- LCD_disp_string(0,0,"X=");
- LCD_disp_string(8,0,"Y=");
- LCD_disp_string(4,1,"Z=");
- while(1)
- {
- if(z_zhou==0)
- {
- LCD_disp_string(7,1,"O N");
- }
-
- else
- {
- // LCD_write_4bit_command(0x01);
- LCD_disp_string(7,1,"OFF");
- }
- rocker=rocker_read(0);
- if(rocker.x<-3)
- {
- rocker.x=-rocker.x+1;
- blue=rocker.x<<1;
- display(blue);
- }
- else
- {
- if(rocker.x>3)
- {
- green=rocker.x<<1;
- display(green);
- }
- else
- {
- green=blue=0;
- }
- }
- if(rocker.y<-3)
- {
- rocker.y=-rocker.y+1;
- yellow=rocker.y<<1;
- display1(yellow);
- }
- else
- {
- if(rocker.y>3)
- {
- red=rocker.y<<1;
- display1(red);
- }
- else
- {
- yellow=red=0;
- }
- }
- }
- }
復制代碼
)
|