در قسمت دهم از آموزش میکروکنترلر STM8 برنامهای بااستفاده از بیپر (Beeper) را آموزش دادیم. تا اینمرحله با همراهی در مجموعه مقالات آموزش میکروکنترلر STM8 برنامههای مختلفی را با STM8 ایجاد کردید. در این قسمت قصد داریم تا گامی مهم برداشته و برنامهای پرکاربرد را به شما آموزش دهیم. با همراهی ما راهاندازی LCD کاراکتری را توسط STM8 فرا بگیرید.
LCD کاراکتری
پساز سون سگمنت و LED، صفحهنمایش کریستال مایع (LCD) کاراکتری یکیاز رایجترین و اساسیترین نمایشگرها بهشمار میآید که برای نمایش سریع دادههای چندگانه مناسب است درحالیکه روشهای دیگر بهراحتی قادربه انجام این کار نیستند.
برای راهاندازی LCD با میکروکنترلر STM8 به کتابخانه آن احتیاجداریم. اما ازآنجاکه STM8 SPI چنین کتابخانهای ندارد، ما مجبور هستیم خودمان دستورات این کتابخانه را بنویسیم. تنها سختافزار موردنیاز برای راهاندازی LCDها، GPIOها هستند، بنابرین راه اندازی LCD ها کار دشواری نیست. در نهایت یکسری دستورات مورد نیاز است. در ابتدا باید فایل کتابخانه را بسازیم. درادامه دستورات کتابخانه قرارداده شدهاست. اگر بخواهم بهطور مختصر بیانکنم ما برای اتصال LCD به ۶پین GPIO نیازداریم. پین خواندن و نوشتن (R/W) در LCD باید به زمین متصلشود. در ادامه طرحبندی آن نشانداده شدهاست.
اتصالات سختافزاری
نمونه کد LCD کاراکتری
lcd.h
#include "stm8s.h" #define lcd_PORT GPIOB #define lcd_RS GPIO_PIN_4 #define LCD_PORT GPIOC #define LCD_EN GPIO_PIN_3 #define LCD_DB4 GPIO_PIN_4 #define LCD_DB5 GPIO_PIN_5 #define LCD_DB6 GPIO_PIN_6 #define LCD_DB7 GPIO_PIN_7 #define clear_display 0x01 #define goto_home 0x02 #define cursor_direction_inc (0x04 | 0x02) #define cursor_direction_dec (0x04 | 0x00) #define display_shift (0x04 | 0x01) #define display_no_shift (0x04 | 0x00) #define display_on (0x08 | 0x04) #define display_off (0x08 | 0x02) #define cursor_on (0x08 | 0x02) #define cursor_off (0x08 | 0x00) #define blink_on (0x08 | 0x01) #define blink_off (0x08 | 0x00) #define _8_pin_interface (0x20 | 0x10) #define _4_pin_interface (0x20 | 0x00) #define _2_row_display (0x20 | 0x08) #define _1_row_display (0x20 | 0x00) #define _5x10_dots (0x20 | 0x40) #define _5x7_dots (0x20 | 0x00) #define DAT 1 #define CMD 0 void LCD_GPIO_init(void); void LCD_init(void); void LCD_send(unsigned char value, unsigned char mode); void LCD_4bit_send(unsigned char lcd_data); void LCD_putstr(char *lcd_string); void LCD_putchar(char char_data); void LCD_clear_home(void); void LCD_goto(unsigned char x_pos, unsigned char y_pos); void toggle_EN_pin(void); void toggle_io(unsigned char lcd_data, unsigned char bit_pos, unsigned char pin_num);
lcd.c
#include "STM8S_lcd.h" void LCD_GPIO_init(void) { int j; GPIO_Init(lcd_PORT, lcd_RS, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(LCD_PORT, LCD_EN, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(LCD_PORT, LCD_DB4, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(LCD_PORT, LCD_DB5, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(LCD_PORT, LCD_DB6, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(LCD_PORT, LCD_DB7, GPIO_MODE_OUT_PP_HIGH_FAST); for (j=0;j<10000;j++); } void LCD_init(void) { LCD_GPIO_init(); toggle_EN_pin(); GPIO_WriteLow(lcd_PORT, lcd_RS); GPIO_WriteLow(LCD_PORT, LCD_DB7); GPIO_WriteLow(LCD_PORT, LCD_DB6); GPIO_WriteHigh(LCD_PORT, LCD_DB5); GPIO_WriteHigh(LCD_PORT, LCD_DB4); toggle_EN_pin(); GPIO_WriteLow(LCD_PORT, LCD_DB7); GPIO_WriteLow(LCD_PORT, LCD_DB6); GPIO_WriteHigh(LCD_PORT, LCD_DB5); GPIO_WriteHigh(LCD_PORT, LCD_DB4); toggle_EN_pin(); GPIO_WriteLow(LCD_PORT, LCD_DB7); GPIO_WriteLow(LCD_PORT, LCD_DB6); GPIO_WriteHigh(LCD_PORT, LCD_DB5); GPIO_WriteHigh(LCD_PORT, LCD_DB4); toggle_EN_pin(); GPIO_WriteLow(LCD_PORT, LCD_DB7); GPIO_WriteLow(LCD_PORT, LCD_DB6); GPIO_WriteHigh(LCD_PORT, LCD_DB5); GPIO_WriteLow(LCD_PORT, LCD_DB4); toggle_EN_pin(); LCD_send((_4_pin_interface | _2_row_display | _5x7_dots), CMD); LCD_send((display_on | cursor_off | blink_off), CMD); LCD_send(clear_display, CMD); LCD_send((cursor_direction_inc | display_no_shift), CMD); } void LCD_send(unsigned char value, unsigned char mode) { switch(mode) { case DAT: { GPIO_WriteHigh(lcd_PORT, lcd_RS); break; } case CMD: { GPIO_WriteLow(lcd_PORT, lcd_RS); break; } } LCD_4bit_send(value); } void LCD_4bit_send(unsigned char lcd_data) { toggle_io(lcd_data, 7, LCD_DB7); toggle_io(lcd_data, 6, LCD_DB6); toggle_io(lcd_data, 5, LCD_DB5); toggle_io(lcd_data, 4, LCD_DB4); toggle_EN_pin(); toggle_io(lcd_data, 3, LCD_DB7); toggle_io(lcd_data, 2, LCD_DB6); toggle_io(lcd_data, 1, LCD_DB5); toggle_io(lcd_data, 0, LCD_DB4); toggle_EN_pin(); } void LCD_putstr(char *lcd_string) { do { LCD_send(*lcd_string++, DAT); }while(*lcd_string != '\0'); } void LCD_putchar(char char_data) { LCD_send(char_data, DAT); } void LCD_clear_home(void) { LCD_send(clear_display, CMD); LCD_send(goto_home, CMD); } void LCD_goto(unsigned char x_pos, unsigned char y_pos) { if(y_pos == 0) { LCD_send((0x80 | x_pos), CMD); } else { LCD_send((0x80 | 0x40 | x_pos), CMD); } } void toggle_EN_pin(void) { int j; GPIO_WriteHigh(LCD_PORT, LCD_EN); for (j=0;j<20000;j++); GPIO_WriteLow(LCD_PORT,LCD_EN); } void toggle_io(unsigned char lcd_data, unsigned char bit_pos, unsigned char pin_num) { bool temp = FALSE; temp = (0x01 & (lcd_data >> bit_pos)); switch(temp) { case TRUE: { GPIO_WriteHigh(LCD_PORT, pin_num); break; } default: { GPIO_WriteLow(LCD_PORT, pin_num); break; } } }
main.c
#include "STM8S.h" #include "STM8S_lcd.h" void clock_setup(void); void GPIO_setup(void); void main(void) { int j; const char txt1[] = {"MICROARENA"}; const char txt2[] = {"Sisoog"}; const char txt3[] = {"STM8S003F"}; const char txt4[] = {"Discovery"}; unsigned char s = 0x00; clock_setup(); GPIO_setup(); LCD_init(); LCD_clear_home(); LCD_goto(3, 0); LCD_putstr(txt1); for(j=0;j<32000;j++); //LCD_clear_home(); LCD_goto(5, 1); LCD_putstr(txt2); for(j=0;j<32000;j++); LCD_clear_home(); for(s = 0; s < 9; s++) { LCD_goto((3 + s), 0); LCD_putchar(txt3[s]); for(j=0;j<32000;j++); } //LCD_clear_home(); for(s = 0; s < 9; s++) { LCD_goto((3 + s), 1); LCD_putchar(txt4[s]); for(j=0;j<32000;j++); } while (TRUE); } void clock_setup(void) { CLK_DeInit(); CLK_HSECmd(DISABLE); CLK_LSICmd(DISABLE); CLK_HSICmd(ENABLE); while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY) == FALSE); CLK_ClockSwitchCmd(ENABLE); CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8); CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1); CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSI, DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_I2C, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_ADC, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_AWU, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_UART1, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER2, DISABLE); CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER4, DISABLE); } void GPIO_setup(void) { GPIO_DeInit(LCD_PORT); }
توضیحات
از آنجا که این کد فقط شامل GPIO ها مسی شود توضیح کمی نیاز دارد. دستورات LCD با مقداردهی اولیه به پین ها می باشد. با این حال، یکی از مهمترین موارد سرعت پردازنده CPU است. اگر ساعت CPU خیلی سریع باشد، ممکن است LCD کار نکند. چون اکثر LCD ها دارای حداکثر فرکانس کاری ۲۵۰کیلوهرتز است. بهتر است فرکانسی زیر ۲۰۰کیلوهرتز داشته باشد.
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV8); CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
در این قسمت باهم راه انداری LCDکاراکتری را یادگرفتیم.در قسمت دوازدهم قصد داریم مبدل آنالوگ به دیجیتال (ADC) را آموزشدهیم. همچنان با ما همراه باشید.
منبع:سیسوگ