STM32液晶顯示HT1621驅動原理及程序代碼

一、HT1621電路分析數組

      HT1621爲32×4即128點內存映像LCD驅動器,包含內嵌的32×4位顯示RAM內存和時基發生器以及WDT看門狗定時器.ide

      HT1621驅動電路以下圖所示:函數

圖1spa

          與單片機相鏈接控制的有9腳CS,3腳WR,12腳DATA,其功能描述以下表。3d

圖2code

二、字符顯示原理orm

         液晶管點亮和熄滅原理分別爲在對應的RAM地址中寫1和寫0.首先須要清楚所驅動控制的液晶的COM-SEG對應關係,而後須要瞭解HT1621的32×4RAM地址映射。對象

         例如要控制的液晶的裝腳成品圖部分以下:blog

圖3ip

        着重看一個液晶數碼管,咱們瞭解原理就行。能夠看到圖3中是第2個液晶數碼管,有7段,分別爲A,B,C,D,E,F,G。也就分別爲下面COM\SEG地址對應關係圖中的2A,2B,2C,2D,2E,2F,2G。

        液晶的顯示字符的部分COM公共端輸出口和SEG段輸出口的分佈以下表所示,同理咱們能夠看到例如:2D對應(SEG5,COM0),2E對應(SEG5,COM1),2F對應(SEG5,COM2),2A對應(SEG5,COM3),2C對應(SEG4,COM1),2G對應(SEG4,COM2),2B對應(SEG4,COM3)。

圖4

         搞清楚咱們要控制的對象以後那,  HT1621的RAM 地址映射以下圖所示:

圖5

        能夠清楚的看到要控制液晶段對應SEG號做爲6位地址,COM號對應做爲4位數據寫入,此時注意4位數據的高低位。寫數據到RAM命令格式爲:101+6位RAM地址+4位數據,其中RAM地址爲SEG序號.

        例如咱們在圖3的第二個液晶數碼管上顯示數字,首先咱們根據圖3獲得地址映射關係,先寫入地址SEG4中的四位數據(COM3,COM2,COM1,COM0),再寫如地址SEG5中的四位數據(COM3,COM2,COM1,COM0),對應關係以下:

SEG4

SEG5

COM3

COM2

COM1

COM0

COM3

COM2

COM1

COM0

2B

2G

2C

T10

2A

2F

2E

2D

        因此若是在圖3中顯示「5」,則在顯示的液晶段對應地址上寫1,不顯示寫0,以下圖所示。因此SEG4地址應寫入的數據爲0110 ,SEG5地址應寫入數據1101。

圖6

三、顯示的保持       

     寫數據過程須要保證寫前無關位數據的保持,所以在單片機程序中開闢32×4數組做爲虛擬ARM,存儲寫前LCD顯示數據.經過與清零,或置位操做實現,例如6位地址Address當前顯示的數據爲Data_last .若Xi(i=0,1,2,3) 位須要保持,則Xi爲1,不然Xi爲0.寫入的數據爲Data_now,變換公式爲:

四、程序

      主要的程序編寫流程以下:

圖7

            程序的參考步驟:①Display_Wendu_1②write_addr_dat_n_wendu③write_mode④write_address⑤write_data_4bit,其中Lcdram數組爲創建的虛擬數組。

 1 unsigned char Lcdram[32]=
 2  {  3                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  4                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  5                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  6                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
 7  };  8 
 9 const unsigned char Wendu[] = //溫度0-9
 10  {  11     0X5F, 0X50, 0X3D, 0X79, 0X72, 0X6B, 0X6F, 0X51, 0X7F, 0X7B 
 12  };  13 ///////////////////////////////////////////////////驅動函數
 14 /*
 15 * LCD 模式寫入  16 * 入口:MODE :COM(命令模式) DAT(數據模式)  17 * 出口:void  18 */
 19 void write_mode(unsigned char MODE)    //寫入模式,數據or命令
 20 {  21     GPIO_ResetBits(GPIOB, HT1621_WR);                                // RW = 0;
 22     delay_us(10);  23     GPIO_SetBits(GPIOB, HT1621_DATA);                                    // DA = 1;
 24     GPIO_SetBits(GPIOB, HT1621_WR);                                    // RW = 1;
 25     delay_us(10);  26 
 27     GPIO_ResetBits(GPIOB, HT1621_WR);                                // RW = 0;
 28     delay_us(10);  29     GPIO_ResetBits(GPIOB, HT1621_DATA);                                // DA = 0;
 30     GPIO_SetBits(GPIOB, HT1621_WR);                                    // RW = 1;
 31     delay_us(10);  32 
 33     GPIO_ResetBits(GPIOB, HT1621_WR);                                // RW = 0;
 34     delay_us(10);  35 
 36     if (0 == MODE)  37  {  38         GPIO_ResetBits(GPIOB, HT1621_DATA);                            // DA = 0;
 39  }  40     else
 41  {  42         GPIO_SetBits(GPIOB, HT1621_DATA);                                // DA = 1;
 43  }  44     delay_us(10);  45     GPIO_SetBits(GPIOB, HT1621_WR);                                    // RW = 1;
 46     delay_us(10);  47 }  48 
 49 /*
 50 * LCD 命令寫入函數  51 * 入口:cbyte ,控制命令字  52 * 出口:void  53 */
 54 void write_command(unsigned char Cbyte)  55 {  56     unsigned char i = 0;  57 
 58     for (i = 0; i < 8; i++)  59  {  60  GPIO_ResetBits(GPIOB, HT1621_WR);  61         if ((Cbyte >> (7 - i)) & 0x01)  62  {  63  GPIO_SetBits(GPIOB, HT1621_DATA);  64  }  65         else
 66  {  67  GPIO_ResetBits(GPIOB, HT1621_DATA);  68  }  69         delay_us(10);  70  GPIO_SetBits(GPIOB, HT1621_WR);  71         delay_us(10);  72  }  73  GPIO_ResetBits(GPIOB, HT1621_WR);  74     delay_us(10);  75  GPIO_ResetBits(GPIOB, HT1621_DATA);  76  GPIO_SetBits(GPIOB, HT1621_WR);  77     delay_us(10);  78 }  79 
 80 /*
 81 * LCD 地址寫入函數  82 * 入口:cbyte,地址  83 * 出口:void  84 */
 85 void write_address(unsigned char Abyte)  86 {  87     unsigned char i = 0;  88     Abyte = Abyte << 2;  89 
 90     for (i = 0; i < 6; i++)  91  {  92  GPIO_ResetBits(GPIOB, HT1621_WR);  93         //delay_us(10);
 94         if ((Abyte >> (7 - i)) & 0x01)  95  {  96  GPIO_SetBits(GPIOB, HT1621_DATA);  97  }  98         else
 99  { 100  GPIO_ResetBits(GPIOB, HT1621_DATA); 101  } 102         delay_us(10); 103  GPIO_SetBits(GPIOB, HT1621_WR); 104         delay_us(10); 105  } 106     
107 } 108 
109 /*
110 * LCD 數據寫入函數 111 * 入口:Dbyte,數據 112 * 出口:void 113 */
114 void write_data_8bit(unsigned char Dbyte) 115 { 116     int i = 0; 117 
118     for (i = 0; i < 8; i++) 119  { 120  GPIO_ResetBits(GPIOB, HT1621_WR); 121         delay_us(10); 122         if ((Dbyte >> (7 - i)) & 0x01) 123  { 124  GPIO_SetBits(GPIOB, HT1621_DATA); 125  } 126         else
127  { 128  GPIO_ResetBits(GPIOB, HT1621_DATA); 129  } 130         delay_us(10); 131  GPIO_SetBits(GPIOB, HT1621_WR); 132         delay_us(10); 133  } 134 } 135 
136 void write_data_4bit(unsigned char Dbyte) 137 { 138     int i = 0; 139 
140     for (i = 0; i < 4; i++) 141  { 142  GPIO_ResetBits(GPIOB, HT1621_WR); 143         //delay_us(10);
144         if ((Dbyte >> (3 - i)) & 0x01) 145  { 146  GPIO_SetBits(GPIOB, HT1621_DATA); 147  } 148         else
149  { 150  GPIO_ResetBits(GPIOB, HT1621_DATA); 151  } 152         delay_us(10); 153  GPIO_SetBits(GPIOB, HT1621_WR); 154         delay_us(10); 155  } 156 } 157 
158 
159 
160 //1621初始化
161 void ht1621_init(void) 162 { 163         GPIO_InitTypeDef GPIO_InitStructure;// declare the structure 
164  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 165 
166         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); 167         memset(&GPIO_InitStructure, 0, sizeof(GPIO_InitTypeDef)); 168         GPIO_InitStructure.GPIO_Pin =  HT1621_WR | HT1621_DATA ;//| HT1621_IRQ
169         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 170         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 171         GPIO_Init(GPIOB, &GPIO_InitStructure); 172 
173         memset(&GPIO_InitStructure, 0, sizeof(GPIO_InitTypeDef)); 174         GPIO_InitStructure.GPIO_Pin = HT1621_CS ;//| HT1621_IRQ
175         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 176         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 177         GPIO_Init(GPIOA, &GPIO_InitStructure); 178 
179 } 180 
181 /*
182 * LCD 初始化,對lcd自身作初始化設置 183 * 入口:void 184 * 出口:void 185 */
186 void lcd_init(void) 187 { 188     ////////////////////////////////////////////////////// 189  GPIO_SetBits(GPIOA, HT1621_CS); 190  GPIO_SetBits(GPIOB, HT1621_WR); 191  GPIO_SetBits(GPIOB, HT1621_DATA); 192     for (ii=0;ii<10000;ii++) 193     {for(j=10;j>0;j--);} 194     //////////////////////////////////////////////////////        
195     GPIO_ResetBits(GPIOA, HT1621_CS);        //CS = 0; 196     //delay_us(10);
197     for (ii=0;ii<10000;ii++) 198     {for(j=10;j>0;j--);} 199     write_mode(COMMAND);    //命令模式
200     write_command(0x01);    //Enable System
201     write_command(0x03);    //Enable Bias
202     write_command(0x04);    //Disable Timer
203     write_command(0x05);    //Disable WDT
204     write_command(0x08);    //Tone OFF
205     write_command(0x18);    //on-chip RC震盪
206     write_command(0x29);    //1/4Duty 1/3Bias
207     write_command(0x80);    //Disable IRQ
208     write_command(0x40);    //Tone Frequency 4kHZ
209     write_command(0xE3);    //Normal Mode
210 
211     GPIO_SetBits(GPIOA, HT1621_CS);  //CS = 1;
212 } 213 
214 /*
215 * LCD 清屏函數 216 * 入口:void 217 * 出口:void 218 */
219 void lcd_clr(void) 220 { 221     write_addr_dat_n(0x0, 0x00, 32);//15
222 } 223 //用於溫度區域寫數據
224 void write_addr_dat_n_wendu(unsigned char _addr, unsigned char _dat, unsigned char n) 225 { 226     
227     unsigned char i = 0; 228     unsigned char _dat_temp1,_dat_temp2; 229     
230     //WriteLcdram(_addr, _dat);
231         
232     
233 
234     GPIO_ResetBits(GPIOA, HT1621_CS);                                // CS = 0;
235  write_mode(DAT); 236     
237     if(Lcdram[_addr]==0x00) 238  { 239  WriteLcdram(_addr, _dat); 240  } 241         if((_addr%2)==0) 242  { 243             _dat_temp1=Lcdram[_addr]; 244             _dat_temp2=(_dat_temp1&0x08)|_dat; 245             
246  write_address(_addr); 247             for (i = 0; i < n; i++) 248  { 249  write_data_4bit(_dat_temp2); 250  } 251         GPIO_SetBits(GPIOA, HT1621_CS);                                    //CS = 1;
252             
253  } 254         else if((_addr%2)!=0) 255  { 256  write_address(_addr); 257             for (i = 0; i < n; i++) 258  { 259  write_data_4bit(_dat); 260  } 261  GPIO_SetBits(GPIOA, HT1621_CS); 262  } 263         
264  WriteLcdram(_addr, _dat_temp2); 265 } 266 
267 //用於溼度區域寫數據
268 void write_addr_dat_n_shidu(unsigned char _addr, unsigned char _dat, unsigned char n) 269 { 270     
271     unsigned char i = 0; 272     unsigned char _dat_temp1,_dat_temp2; 273     
274     //WriteLcdram(_addr, _dat);
275         
276     
277 
278     GPIO_ResetBits(GPIOA, HT1621_CS);                                // CS = 0;
279  write_mode(DAT); 280     
281     if(Lcdram[_addr]==0x00) 282  { 283  WriteLcdram(_addr, _dat); 284  } 285         if((_addr%2)==0) 286  { 287             _dat_temp1=Lcdram[_addr]; 288             _dat_temp2=(_dat_temp1&0x01)|_dat; 289             
290  write_address(_addr); 291             for (i = 0; i < n; i++) 292  { 293  write_data_4bit(_dat_temp2); 294  } 295         GPIO_SetBits(GPIOA, HT1621_CS);                                    //CS = 1;
296             
297  } 298         else if((_addr%2)!=0) 299  { 300  write_address(_addr); 301             for (i = 0; i < n; i++) 302  { 303  write_data_4bit(_dat); 304  } 305  GPIO_SetBits(GPIOA, HT1621_CS); 306  } 307         
308  WriteLcdram(_addr, _dat_temp2); 309 } 310 
311 
312 //用於底部數字寫數據
313 void write_addr_dat_n_others(unsigned char _addr, unsigned char _dat, unsigned char n) 314 { 315     
316     unsigned char i = 0; 317     unsigned char _dat_temp1,_dat_temp2; 318     GPIO_ResetBits(GPIOA, HT1621_CS);                                // CS = 0;
319  write_mode(DAT); 320     
321     if(Lcdram[_addr]==0x00) 322  { 323  WriteLcdram(_addr, _dat); 324         
325  } 326         if((_addr%2)==0) 327  { 328             _dat_temp1=Lcdram[_addr]; 329             _dat_temp2=(_dat_temp1&0x01)|_dat; 330             
331  write_address(_addr); 332             for (i = 0; i < n; i++) 333  { 334  write_data_4bit(_dat_temp2); 335  } 336         GPIO_SetBits(GPIOA, HT1621_CS);                                    //CS = 1;
337             
338  } 339         else if((_addr%2)!=0) 340  { 341  write_address(_addr); 342             for (i = 0; i < n; i++) 343  { 344  write_data_4bit(_dat); 345  } 346  GPIO_SetBits(GPIOA, HT1621_CS); 347  } 348         
349         //WriteLcdram(_addr, _dat);
350  WriteLcdram(_addr, _dat_temp2); 351 } 352 
353 //用於字符寫數據
354 void write_addr_dat_n_char(unsigned char _addr, unsigned char _dat, unsigned char state) 355 { 356     
357     unsigned char i = 0; 358     unsigned char _dat_temp1,_dat_temp2; 359     
360 
361         GPIO_ResetBits(GPIOA, HT1621_CS);                                // CS = 0;
362  write_mode(DAT); 363             
364                 _dat_temp1=Lcdram[_addr]; 365             if(state==1) 366  { 367                 
368                 _dat_temp2=(_dat_temp1|_dat); 369  } 370             else if(state==0) 371  { 372                 _dat_temp2=(_dat_temp1&(~_dat)); 373  } 374  write_address(_addr); 375             
376                 for (i = 0; i < 1; i++) 377  { 378  write_data_4bit(_dat_temp2); 379  } 380             GPIO_SetBits(GPIOA, HT1621_CS);                                    //CS = 1;
381  WriteLcdram(_addr, _dat_temp2); 382         
383         
384         
385     
386 } 387 //顯示溫度 388 //入口:pos,顯示位置,地址0、二、4分別爲從右到左的三個數字 389 // num:要顯示的一位數
390 void Display_Wendu_1(unsigned char add, unsigned char num ) 391 { 392     unsigned char n,i,j; 393     n=getChr_Wendu(num); 394     i=(n&0xF0)>>4; 395     j=n&0x0F; 396     write_addr_dat_n_wendu(add,i,1); 397     write_addr_dat_n_wendu(add+1,j,1); 398     
399 } 400 
401 
402 //溫度數據轉換,lcd.c內部使用
403  unsigned char getChr_Wendu(unsigned char c) 404  { 405      unsigned char i; 406         for ( i = 0; i < 10; ++i) 407  { 408             if (c == i) 409  { 410                 return Wendu[i]; 411  } 412  } 413  } 414 
415 //更新lcdram數組
416 void WriteLcdram(unsigned char add, unsigned char data) 417 { 418     
419     Lcdram[add]=data; 420     
421 }
View Code

 當軒不是憐蒼翠,只要人知耐歲寒。

轉載需說明出處,筆者總結以前的知識,與你們分享,有問題的能夠留給我哦~

相關文章
相關標籤/搜索