This is a clock made using mbed timers on stm32

Committer:
EDISON_NGUNJIRI
Date:
Sun May 15 11:04:11 2022 +0000
Revision:
1:ec3114a06678
Parent:
0:824096cc05af
CLOCK TIMER MBED

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Yar 0:824096cc05af 1 #include "LiquidCrystal_I2C.h"
Yar 0:824096cc05af 2 #include "mbed.h"
Yar 0:824096cc05af 3
Yar 0:824096cc05af 4 // When the display powers up, it is configured as follows:
Yar 0:824096cc05af 5 //
Yar 0:824096cc05af 6 // 1. Display clear
Yar 0:824096cc05af 7 // 2. Function set:
Yar 0:824096cc05af 8 // DL = 1; 8-bit interface data
Yar 0:824096cc05af 9 // N = 0; 1-line display
Yar 0:824096cc05af 10 // F = 0; 5x8 dot character font
Yar 0:824096cc05af 11 // 3. Display on/off control:
Yar 0:824096cc05af 12 // D = 0; Display off
Yar 0:824096cc05af 13 // C = 0; Cursor off
Yar 0:824096cc05af 14 // B = 0; Blinking off
Yar 0:824096cc05af 15 // 4. Entry mode set:
Yar 0:824096cc05af 16 // I/D = 1; Increment by 1
Yar 0:824096cc05af 17 // S = 0; No shift
Yar 0:824096cc05af 18 //
Yar 0:824096cc05af 19 // Note, however, that resetting the Arduino doesn't reset the LCD, so we
Yar 0:824096cc05af 20 // can't assume that its in that state when a sketch starts (and the
Yar 0:824096cc05af 21 // LiquidCrystal constructor is called).
Yar 0:824096cc05af 22
Yar 0:824096cc05af 23
EDISON_NGUNJIRI 1:ec3114a06678 24 I2C _i2c(PB_9, PB_8); // SDA, SCL
Yar 0:824096cc05af 25
Yar 0:824096cc05af 26 LiquidCrystal_I2C::LiquidCrystal_I2C(unsigned char lcd_addr, unsigned char lcd_cols, unsigned char lcd_rows, unsigned char charsize)
Yar 0:824096cc05af 27 {
Yar 0:824096cc05af 28 _addr = lcd_addr;
Yar 0:824096cc05af 29 _cols = lcd_cols;
Yar 0:824096cc05af 30 _rows = lcd_rows;
Yar 0:824096cc05af 31 _charsize = charsize;
Yar 0:824096cc05af 32 _backlightval = LCD_BACKLIGHT;
Yar 0:824096cc05af 33 }
Yar 0:824096cc05af 34
Yar 0:824096cc05af 35 void LiquidCrystal_I2C::begin() {
Yar 0:824096cc05af 36 //Wire.begin();
Yar 0:824096cc05af 37 _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
Yar 0:824096cc05af 38
Yar 0:824096cc05af 39 if (_rows > 1) {
Yar 0:824096cc05af 40 _displayfunction |= LCD_2LINE;
Yar 0:824096cc05af 41 }
Yar 0:824096cc05af 42
Yar 0:824096cc05af 43 // for some 1 line displays you can select a 10 pixel high font
Yar 0:824096cc05af 44 if ((_charsize != 0) && (_rows == 1)) {
Yar 0:824096cc05af 45 _displayfunction |= LCD_5x10DOTS;
Yar 0:824096cc05af 46 }
Yar 0:824096cc05af 47
Yar 0:824096cc05af 48 // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
Yar 0:824096cc05af 49 // according to datasheet, we need at least 40ms after power rises above 2.7V
Yar 0:824096cc05af 50 // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
EDISON_NGUNJIRI 1:ec3114a06678 51 wait_us(50000);
Yar 0:824096cc05af 52
Yar 0:824096cc05af 53 // Now we pull both RS and R/W low to begin commands
Yar 0:824096cc05af 54 expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1)
EDISON_NGUNJIRI 1:ec3114a06678 55 wait_us(1000000);
Yar 0:824096cc05af 56
Yar 0:824096cc05af 57 //put the LCD into 4 bit mode
Yar 0:824096cc05af 58 // this is according to the hitachi HD44780 datasheet
Yar 0:824096cc05af 59 // figure 24, pg 46
Yar 0:824096cc05af 60
Yar 0:824096cc05af 61 // we start in 8bit mode, try to set 4 bit mode
Yar 0:824096cc05af 62 write4bits(0x03 << 4);
Yar 0:824096cc05af 63 wait_us(4500); // wait min 4.1ms
Yar 0:824096cc05af 64
Yar 0:824096cc05af 65 // second try
Yar 0:824096cc05af 66 write4bits(0x03 << 4);
Yar 0:824096cc05af 67 wait_us(4500); // wait min 4.1ms
Yar 0:824096cc05af 68
Yar 0:824096cc05af 69 // third go!
Yar 0:824096cc05af 70 write4bits(0x03 << 4);
Yar 0:824096cc05af 71 wait_us(150);
Yar 0:824096cc05af 72
Yar 0:824096cc05af 73 // finally, set to 4-bit interface
Yar 0:824096cc05af 74 write4bits(0x02 << 4);
Yar 0:824096cc05af 75
Yar 0:824096cc05af 76 // set # lines, font size, etc.
Yar 0:824096cc05af 77 command(LCD_FUNCTIONSET | _displayfunction);
Yar 0:824096cc05af 78
Yar 0:824096cc05af 79 // turn the display on with no cursor or blinking default
Yar 0:824096cc05af 80 _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
Yar 0:824096cc05af 81 display();
Yar 0:824096cc05af 82
Yar 0:824096cc05af 83 // clear it off
Yar 0:824096cc05af 84 clear();
Yar 0:824096cc05af 85
Yar 0:824096cc05af 86 // Initialize to default text direction (for roman languages)
Yar 0:824096cc05af 87 _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
Yar 0:824096cc05af 88
Yar 0:824096cc05af 89 // set the entry mode
Yar 0:824096cc05af 90 command(LCD_ENTRYMODESET | _displaymode);
Yar 0:824096cc05af 91
Yar 0:824096cc05af 92 home();
Yar 0:824096cc05af 93 }
Yar 0:824096cc05af 94
Yar 0:824096cc05af 95 /********** high level commands, for the user! */
Yar 0:824096cc05af 96 void LiquidCrystal_I2C::clear(){
Yar 0:824096cc05af 97 command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
Yar 0:824096cc05af 98 wait_us(2000); // this command takes a long time!
Yar 0:824096cc05af 99 }
Yar 0:824096cc05af 100
Yar 0:824096cc05af 101 void LiquidCrystal_I2C::home(){
Yar 0:824096cc05af 102 command(LCD_RETURNHOME); // set cursor position to zero
Yar 0:824096cc05af 103 wait_us(2000); // this command takes a long time!
Yar 0:824096cc05af 104 }
Yar 0:824096cc05af 105
Yar 0:824096cc05af 106 void LiquidCrystal_I2C::setCursor(unsigned char col, unsigned char row){
Yar 0:824096cc05af 107 int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
Yar 0:824096cc05af 108 if (row > _rows) {
Yar 0:824096cc05af 109 row = _rows-1; // we count rows starting w/0
Yar 0:824096cc05af 110 }
Yar 0:824096cc05af 111 command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
Yar 0:824096cc05af 112 }
Yar 0:824096cc05af 113
Yar 0:824096cc05af 114 // Turn the display on/off (quickly)
Yar 0:824096cc05af 115 void LiquidCrystal_I2C::noDisplay() {
Yar 0:824096cc05af 116 _displaycontrol &= ~LCD_DISPLAYON;
Yar 0:824096cc05af 117 command(LCD_DISPLAYCONTROL | _displaycontrol);
Yar 0:824096cc05af 118 }
Yar 0:824096cc05af 119 void LiquidCrystal_I2C::display() {
Yar 0:824096cc05af 120 _displaycontrol |= LCD_DISPLAYON;
Yar 0:824096cc05af 121 command(LCD_DISPLAYCONTROL | _displaycontrol);
Yar 0:824096cc05af 122 }
Yar 0:824096cc05af 123
Yar 0:824096cc05af 124 // Turns the underline cursor on/off
Yar 0:824096cc05af 125 void LiquidCrystal_I2C::noCursor() {
Yar 0:824096cc05af 126 _displaycontrol &= ~LCD_CURSORON;
Yar 0:824096cc05af 127 command(LCD_DISPLAYCONTROL | _displaycontrol);
Yar 0:824096cc05af 128 }
Yar 0:824096cc05af 129 void LiquidCrystal_I2C::cursor() {
Yar 0:824096cc05af 130 _displaycontrol |= LCD_CURSORON;
Yar 0:824096cc05af 131 command(LCD_DISPLAYCONTROL | _displaycontrol);
Yar 0:824096cc05af 132 }
Yar 0:824096cc05af 133
Yar 0:824096cc05af 134 // Turn on and off the blinking cursor
Yar 0:824096cc05af 135 void LiquidCrystal_I2C::noBlink() {
Yar 0:824096cc05af 136 _displaycontrol &= ~LCD_BLINKON;
Yar 0:824096cc05af 137 command(LCD_DISPLAYCONTROL | _displaycontrol);
Yar 0:824096cc05af 138 }
Yar 0:824096cc05af 139 void LiquidCrystal_I2C::blink() {
Yar 0:824096cc05af 140 _displaycontrol |= LCD_BLINKON;
Yar 0:824096cc05af 141 command(LCD_DISPLAYCONTROL | _displaycontrol);
Yar 0:824096cc05af 142 }
Yar 0:824096cc05af 143
Yar 0:824096cc05af 144 // These commands scroll the display without changing the RAM
Yar 0:824096cc05af 145 void LiquidCrystal_I2C::scrollDisplayLeft(void) {
Yar 0:824096cc05af 146 command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
Yar 0:824096cc05af 147 }
Yar 0:824096cc05af 148 void LiquidCrystal_I2C::scrollDisplayRight(void) {
Yar 0:824096cc05af 149 command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
Yar 0:824096cc05af 150 }
Yar 0:824096cc05af 151
Yar 0:824096cc05af 152 // This is for text that flows Left to Right
Yar 0:824096cc05af 153 void LiquidCrystal_I2C::leftToRight(void) {
Yar 0:824096cc05af 154 _displaymode |= LCD_ENTRYLEFT;
Yar 0:824096cc05af 155 command(LCD_ENTRYMODESET | _displaymode);
Yar 0:824096cc05af 156 }
Yar 0:824096cc05af 157
Yar 0:824096cc05af 158 // This is for text that flows Right to Left
Yar 0:824096cc05af 159 void LiquidCrystal_I2C::rightToLeft(void) {
Yar 0:824096cc05af 160 _displaymode &= ~LCD_ENTRYLEFT;
Yar 0:824096cc05af 161 command(LCD_ENTRYMODESET | _displaymode);
Yar 0:824096cc05af 162 }
Yar 0:824096cc05af 163
Yar 0:824096cc05af 164 // This will 'right justify' text from the cursor
Yar 0:824096cc05af 165 void LiquidCrystal_I2C::autoscroll(void) {
Yar 0:824096cc05af 166 _displaymode |= LCD_ENTRYSHIFTINCREMENT;
Yar 0:824096cc05af 167 command(LCD_ENTRYMODESET | _displaymode);
Yar 0:824096cc05af 168 }
Yar 0:824096cc05af 169
Yar 0:824096cc05af 170 // This will 'left justify' text from the cursor
Yar 0:824096cc05af 171 void LiquidCrystal_I2C::noAutoscroll(void) {
Yar 0:824096cc05af 172 _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
Yar 0:824096cc05af 173 command(LCD_ENTRYMODESET | _displaymode);
Yar 0:824096cc05af 174 }
Yar 0:824096cc05af 175
Yar 0:824096cc05af 176 // Allows us to fill the first 8 CGRAM locations
Yar 0:824096cc05af 177 // with custom characters
Yar 0:824096cc05af 178 void LiquidCrystal_I2C::createChar(unsigned char location, unsigned char charmap[]) {
Yar 0:824096cc05af 179 location &= 0x7; // we only have 8 locations 0-7
Yar 0:824096cc05af 180 command(LCD_SETCGRAMADDR | (location << 3));
Yar 0:824096cc05af 181 for (int i=0; i<8; i++) {
Yar 0:824096cc05af 182 write(charmap[i]);
Yar 0:824096cc05af 183 }
Yar 0:824096cc05af 184 }
Yar 0:824096cc05af 185
Yar 0:824096cc05af 186 // Turn the (optional) backlight off/on
Yar 0:824096cc05af 187 void LiquidCrystal_I2C::noBacklight(void) {
Yar 0:824096cc05af 188 _backlightval=LCD_NOBACKLIGHT;
Yar 0:824096cc05af 189 expanderWrite(0);
Yar 0:824096cc05af 190 }
Yar 0:824096cc05af 191
Yar 0:824096cc05af 192 void LiquidCrystal_I2C::backlight(void) {
Yar 0:824096cc05af 193 _backlightval=LCD_BACKLIGHT;
Yar 0:824096cc05af 194 expanderWrite(0);
Yar 0:824096cc05af 195 }
Yar 0:824096cc05af 196 bool LiquidCrystal_I2C::getBacklight() {
Yar 0:824096cc05af 197 return _backlightval == LCD_BACKLIGHT;
Yar 0:824096cc05af 198 }
Yar 0:824096cc05af 199
Yar 0:824096cc05af 200
Yar 0:824096cc05af 201 /*********** mid level commands, for sending data/cmds */
Yar 0:824096cc05af 202
Yar 0:824096cc05af 203 inline void LiquidCrystal_I2C::command(unsigned char value) {
Yar 0:824096cc05af 204 send(value, 0);
Yar 0:824096cc05af 205 }
Yar 0:824096cc05af 206
Yar 0:824096cc05af 207 inline int LiquidCrystal_I2C::write(unsigned char value) {
Yar 0:824096cc05af 208 send(value, Rs);
Yar 0:824096cc05af 209 return 1;
Yar 0:824096cc05af 210 }
Yar 0:824096cc05af 211
Yar 0:824096cc05af 212
Yar 0:824096cc05af 213 /************ low level data pushing commands **********/
Yar 0:824096cc05af 214
Yar 0:824096cc05af 215 // write either command or data
Yar 0:824096cc05af 216 void LiquidCrystal_I2C::send(unsigned char value, unsigned char mode) {
Yar 0:824096cc05af 217 unsigned char highnib=value&0xf0;
Yar 0:824096cc05af 218 unsigned char lownib=(value<<4)&0xf0;
Yar 0:824096cc05af 219 write4bits((highnib)|mode);
Yar 0:824096cc05af 220 write4bits((lownib)|mode);
Yar 0:824096cc05af 221 }
Yar 0:824096cc05af 222
Yar 0:824096cc05af 223 void LiquidCrystal_I2C::write4bits(unsigned char value) {
Yar 0:824096cc05af 224 expanderWrite(value);
Yar 0:824096cc05af 225 pulseEnable(value);
Yar 0:824096cc05af 226 }
Yar 0:824096cc05af 227
Yar 0:824096cc05af 228 void LiquidCrystal_I2C::expanderWrite(unsigned char _data){
Yar 0:824096cc05af 229 char data_write[2];
Yar 0:824096cc05af 230 data_write[0] = _data | _backlightval;
Yar 0:824096cc05af 231 //Wire.beginTransmission(_addr);
Yar 0:824096cc05af 232 //Wire.write((int)(_data) | _backlightval);
Yar 0:824096cc05af 233 //Wire.endTransmission();
Yar 0:824096cc05af 234 _i2c.write(_addr, data_write, 1, 0);
Yar 0:824096cc05af 235 _i2c.stop();
Yar 0:824096cc05af 236 }
Yar 0:824096cc05af 237
Yar 0:824096cc05af 238 void LiquidCrystal_I2C::pulseEnable(unsigned char _data){
Yar 0:824096cc05af 239 expanderWrite(_data | En); // En high
Yar 0:824096cc05af 240 wait_us(1); // enable pulse must be >450ns
Yar 0:824096cc05af 241
Yar 0:824096cc05af 242 expanderWrite(_data & ~En); // En low
Yar 0:824096cc05af 243 wait_us(50); // commands need > 37us to settle
Yar 0:824096cc05af 244 }
Yar 0:824096cc05af 245
Yar 0:824096cc05af 246 void LiquidCrystal_I2C::load_custom_character(unsigned char char_num, unsigned char *rows){
Yar 0:824096cc05af 247 createChar(char_num, rows);
Yar 0:824096cc05af 248 }
Yar 0:824096cc05af 249
Yar 0:824096cc05af 250 void LiquidCrystal_I2C::setBacklight(unsigned char new_val){
Yar 0:824096cc05af 251 if (new_val) {
Yar 0:824096cc05af 252 backlight(); // turn backlight on
Yar 0:824096cc05af 253 } else {
Yar 0:824096cc05af 254 noBacklight(); // turn backlight off
Yar 0:824096cc05af 255 }
Yar 0:824096cc05af 256 }
Yar 0:824096cc05af 257
Yar 0:824096cc05af 258 void LiquidCrystal_I2C::printstr(const char c[]){
Yar 0:824096cc05af 259 //This function is not identical to the function used for "real" I2C displays
Yar 0:824096cc05af 260 //it's here so the user sketch doesn't have to be changed
Yar 0:824096cc05af 261 //print(c);
Yar 0:824096cc05af 262 }
Yar 0:824096cc05af 263
Yar 0:824096cc05af 264 int LiquidCrystal_I2C::print(const char* text) {
Yar 0:824096cc05af 265
Yar 0:824096cc05af 266 while (*text !=0) {
Yar 0:824096cc05af 267 //_putc(*text);
Yar 0:824096cc05af 268 send(*text, Rs);
Yar 0:824096cc05af 269 text++;
Yar 0:824096cc05af 270 }
Yar 0:824096cc05af 271 return 0;
Yar 0:824096cc05af 272 }
Yar 0:824096cc05af 273
Yar 0:824096cc05af 274 /*
Yar 0:824096cc05af 275 void lcd_dat(unsigned char p)
Yar 0:824096cc05af 276 {
Yar 0:824096cc05af 277 PORTC |= (1 << RS)|(1 << EN); // RS = 1, EN = 1 (начало записи команды в LCD)
Yar 0:824096cc05af 278 PORTD = p; // Вывод команды на шину DB0-7 LCD
Yar 0:824096cc05af 279 _delay_us(100); // Длительность сигнала EN
Yar 0:824096cc05af 280 PORTC &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
Yar 0:824096cc05af 281 _delay_us(100); // Пауза для выполнения команды
Yar 0:824096cc05af 282 }
Yar 0:824096cc05af 283 */