STM32VL-Discoveryに市販のLCDモジュールTC1602E-06T(SC1602互換仕様)を接続して表示するサンプルです。(本来ならば、BUSYをチェックする必要がありますが、今回のサンプルでは省略していますのでご注意ください。)
まず、ポートの割当です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#define LCD_SC1602_Dn 8 #define LCD_SC1602_D0 GPIO_Pin_0 #define LCD_SC1602_D1 GPIO_Pin_1 #define LCD_SC1602_D2 GPIO_Pin_2 #define LCD_SC1602_D3 GPIO_Pin_3 #define LCD_SC1602_D4 GPIO_Pin_4 #define LCD_SC1602_D5 GPIO_Pin_5 #define LCD_SC1602_D6 GPIO_Pin_6 #define LCD_SC1602_D7 GPIO_Pin_7 #define LCD_SC1602_DATA_PORT GPIOC #define LCD_SC1602_DATA_GPIO_CLOCK RCC_APB2Periph_GPIOC #define LCD_SC1602_CTL_NUM 4 #define LCD_SC1602_CTL_RS GPIO_Pin_10 #define LCD_SC1602_CTL_RW GPIO_Pin_11 #define LCD_SC1602_CTL_EN GPIO_Pin_12 #define LCD_SC1602_NVCC GPIO_Pin_13 #define LCD_SC1602_CTL_PORT GPIOC #define LCD_SC1602_CTL_CLOCK RCC_APB2Periph_GPIOC |
- PC0〜PC7を各々D0〜D7のデータライン
- PC10 RS
- PC11 RW
- PC12 EN
に割り当てています。
また、チャージポンプ用の出力を PC13に割り当てています。
初期化用の配列等です。
サンプルプログラムのLEDポートの初期化にあわせています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
const uint32_t GPIO_CLK_SC1602_DATA[LCD_SC1602_Dn] = { LCD_SC1602_DATA_GPIO_CLOCK, LCD_SC1602_DATA_GPIO_CLOCK, LCD_SC1602_DATA_GPIO_CLOCK, LCD_SC1602_DATA_GPIO_CLOCK, LCD_SC1602_DATA_GPIO_CLOCK, LCD_SC1602_DATA_GPIO_CLOCK, LCD_SC1602_DATA_GPIO_CLOCK, LCD_SC1602_DATA_GPIO_CLOCK }; const uint16_t GPIO_PIN_SC1602_DATA[LCD_SC1602_Dn] = { LCD_SC1602_D0, LCD_SC1602_D1, LCD_SC1602_D2, LCD_SC1602_D3, LCD_SC1602_D4, LCD_SC1602_D5, LCD_SC1602_D6, LCD_SC1602_D7, }; GPIO_TypeDef* GPIO_PORT_SC1602_DATA[LCD_SC1602_Dn] = { LCD_SC1602_DATA_PORT, LCD_SC1602_DATA_PORT, LCD_SC1602_DATA_PORT, LCD_SC1602_DATA_PORT, LCD_SC1602_DATA_PORT, LCD_SC1602_DATA_PORT, LCD_SC1602_DATA_PORT, LCD_SC1602_DATA_PORT }; const uint32_t GPIO_CLK_SC1602_CTL[LCD_SC1602_CTL_NUM] = { LCD_SC1602_CTL_CLOCK, LCD_SC1602_CTL_CLOCK, LCD_SC1602_CTL_CLOCK, LCD_SC1602_CTL_CLOCK }; const uint16_t GPIO_PIN_SC1602_CTL[LCD_SC1602_CTL_NUM] = { LCD_SC1602_CTL_RS, LCD_SC1602_CTL_RW, LCD_SC1602_CTL_EN, LCD_SC1602_NVCC }; GPIO_TypeDef* GPIO_PORT_SC1602_CTL[LCD_SC1602_CTL_NUM] = { LCD_SC1602_CTL_PORT, LCD_SC1602_CTL_PORT, LCD_SC1602_CTL_PORT, LCD_SC1602_CTL_PORT }; |
初期化関数です。
サンプルコードに合わせました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
void stm32vldiscoverySC1062init(void) { //initialize port setting GPIO_InitTypeDef GPIO_InitStructure; uint8_t i; /* Enable the LCD SC1602 peripheral */ for(i = 0; i < LCD_SC1602_Dn; i++){ RCC_APB2PeriphClockCmd(GPIO_CLK_SC1602_DATA[i], ENABLE); /* Configure the DATA pin */ GPIO_InitStructure.GPIO_Pin = GPIO_PIN_SC1602_DATA[i]; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIO_PORT_SC1602_DATA[i], &GPIO_InitStructure); } for(i = 0; i < LCD_SC1602_CTL_NUM; i++){ RCC_APB2PeriphClockCmd(GPIO_CLK_SC1602_CTL[i], ENABLE); /* Configure the GPIO CTRL pin */ GPIO_InitStructure.GPIO_Pin = GPIO_PIN_SC1602_CTL[i]; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIO_PORT_SC1602_CTL[i], &GPIO_InitStructure); } } |
各コントロールポートの制御です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#define DELAY shortDelay(5) #define DELAY_CMD Delay(10) extern void Delay(uint32_t nTime); void shortDelay(volatile uint32_t n) { while(n--); } inline void lcdSC1602RWControl(BitAction bitVal) { GPIO_WriteBit(LCD_SC1602_CTL_PORT, LCD_SC1602_CTL_RW, bitVal); } inline void lcdSC1602RSControl(BitAction bitVal) { GPIO_WriteBit(LCD_SC1602_CTL_PORT, LCD_SC1602_CTL_RS, bitVal); } inline void lcdSC1602EnbControl(BitAction bitVal) { GPIO_WriteBit(LCD_SC1602_CTL_PORT, LCD_SC1602_CTL_EN, bitVal); } inline void lcsSC1602NVccControl(BitAction bitVal) { GPIO_WriteBit(LCD_SC1602_CTL_PORT, LCD_SC1602_NVCC, bitVal); } |
コントロールコード送信用の関数です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
void lcdSC1602SetData(uint8_t data) { uint16_t oreg; oreg = GPIO_ReadOutputData(LCD_SC1602_DATA_PORT); oreg &= 0xff00; oreg |= data; GPIO_Write(LCD_SC1602_DATA_PORT, oreg); } void lcdSC1602SendCommand(uint8_t data) { lcdSC1602EnbControl(Bit_RESET); lcdSC1602RSControl(Bit_RESET); lcdSC1602RWControl(Bit_RESET); DELAY; lcdSC1602EnbControl(Bit_SET); DELAY; lcdSC1602SetData(data); DELAY; lcdSC1602EnbControl(Bit_RESET); } void lcdSC1602ClearDisplay(void) { lcdSC1602SendCommand(0x01); } void lcdSC1602EntryModeSet(void) { lcdSC1602SendCommand(0b00000110); } void lcdSC1602ReturnHome( ) { lcdSC1602SendCommand(0x02); } void lcdSC1602SetDDRam(uint8_t adrs) { lcdSC1602SendCommand(0x80 | (adrs & 0x7f)); } void lcdSC1602FunctionSet(void) { lcdSC1602SendCommand(0b00111111); } void lcdSC1602DisplayOn(bool on) { uint8_t d; if(on){ d = 0b00001110; }else{ d = 0b00001000; } lcdSC1602SendCommand(d); } |
いよいよ、文字を表示させる部分です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
void lcdSC1602PutChar(uint8_t chr) { lcdSC1602EnbControl(Bit_RESET); lcdSC1602RSControl(Bit_SET); lcdSC1602RWControl(Bit_RESET); DELAY; lcdSC1602EnbControl(Bit_SET); DELAY; lcdSC1602SetData(chr); DELAY; lcdSC1602EnbControl(Bit_RESET); DELAY; lcdSC1602RSControl(Bit_RESET); } void lcdSC1602SetCharPosition(uint8_t col, uint8_t row) { uint8_t d; d = 0; if(row > 15){ col = 1; row -= 16; } if(col == 0){ //Line 1 d = 0b10000000; } else{ //Line 2 d |= 0b11000000; } d |= row; lcdSC1602SendCommand(d); } |
文字出力用のテスト関数です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
void stm32vldiscoverySC1062DataTest(void) { uint8_t i; stm32vldiscoverySC1062init(); lcdSC1602FunctionSet(); DELAY_CMD; lcdSC1602FunctionSet(); DELAY_CMD; lcdSC1602FunctionSet(); DELAY_CMD; lcdSC1602FunctionSet(); DELAY_CMD; lcdSC1602DisplayOn(FALSE); DELAY_CMD; lcdSC1602ClearDisplay(); DELAY_CMD; lcdSC1602EntryModeSet(); DELAY_CMD; lcdSC1602DisplayOn(TRUE); DELAY_CMD; const uint8_t m[] = "http://www.e-momonga.com/honkytonk/"; for(i = 0; i < sizeof(m)-1; i++){ if(i == 16){ lcdSC1602SetCharPosition(1, 0); DELAY_CMD; } lcdSC1602PutChar(m[i]); DELAY_CMD; } } |
lcdSC1602FunctionSet()を数回送信しているのがミソです。
mainのどこからか stm32vldiscoverySC1062DataTest()をCallしてください。