• Объявления

    • admin

      Просьба всем принять участие!   24.11.2017

      На форуме разыгрывается спектроанализатор Arinst SSA-TG LC (цена 18500 руб). Просьба всем перейти по ссылке ниже и принять участие!
artos5

Stm32F100 + Hd44780 = Глюк Библиотеки

45 сообщений в этой теме

artos5    285

Добрый день уважаемые! Уже второй день бьюсь над кодом... не получается решить проблему.

Проблема заключается в следующем:

Если в вечном цикле постоянно слать текст в контроллер , то на дисплее отображается полная фигня... отображается эта фигня во второй строке. Вот видео пример:

Но! Если в вечном цикле я отправляю в дисплей не постоянно данные , а только раз сразу после изменения - то индикатор отображает данные корректно....

Вот тут: http://easystm32.ru/...ary-for-hd44780

я взял за основу библиотеку.

Вот сами библиотеки:

#include "hd44780_driver.h"

void lcd_delay(void) {
volatile uint32_t tmpvar;
for (tmpvar=4000;tmpvar!=0;tmpvar--);
}

void lcd_init() {
LCD_PORT->CRH |= LCD_PORT_CRH_S;
LCD_PORT->CRL |= LCD_PORT_CRL_S;
LCD_PORT->CRH &= ~(LCD_PORT_CRH_C);
LCD_PORT->CRL &= ~(LCD_PORT_CRL_C);
lcd_delay();
lcd_delay();
lcd_delay();
lcd_delay();

lcd_set_4bit_mode();
lcd_set_state(LCD_ENABLE,CURSOR_ENABLE,NO_BLINK);
lcd_clear();
lcd_send(0x06,COMMAND);
}

void lcd_set_user_char(uint8_t char_num, uint8_t * char_data) {
uint8_t i;
lcd_send(((1<<6) | (char_num * 8) ), COMMAND);
for (i=0;i<=7;i++) {
lcd_send(char_data[i],DATA);
}
lcd_send((1<<7), COMMAND);
}

void lcd_set_xy(uint8_t x, uint8_t y) {
if (y==0) {
lcd_send( ((1<<7) | (x)),COMMAND);
} else {
lcd_send( ((3<<6) | (x)),COMMAND);
}
}


void lcd_out(char * txt) {
while(*txt) {
lcd_send(*txt,DATA);
txt++;
}
txt=0;
}

void lcd_clear(void) {
lcd_send(0x01,COMMAND);
}

void lcd_set_state(lcd_state state, cursor_state cur_state, cursor_mode cur_mode) {
if (state==LCD_DISABLE) {
lcd_send(0x08,COMMAND);
} else {
if (cur_state==CURSOR_DISABLE) {
if (cur_mode==NO_BLINK) {
lcd_send(0x0C,COMMAND);
} else {
lcd_send(0x0D,COMMAND);
}
} else {
if (cur_mode==NO_BLINK) {
lcd_send(0x0E,COMMAND);
} else {
lcd_send(0x0F,COMMAND);
}
}
}
}

void lcd_set_4bit_mode(void) {

LCD_PORT->BSRR=(LCD_DB7_BC | LCD_DB6_BC | LCD_DB5_BC | LCD_DB4_BC | LCD_CD_BC | LCD_EN_BC);
LCD_PORT->BSRR=(LCD_DB5_BS);

LCD_PORT->BSRR=LCD_EN_BS;
lcd_delay();
LCD_PORT->BSRR=LCD_EN_BC;
lcd_delay();

LCD_PORT->BSRR=(LCD_DB7_BC | LCD_DB6_BC | LCD_DB5_BC | LCD_DB4_BC | LCD_CD_BC | LCD_EN_BC);
LCD_PORT->BSRR=(LCD_DB5_BS);

LCD_PORT->BSRR=LCD_EN_BS;
lcd_delay();
LCD_PORT->BSRR=LCD_EN_BC;
lcd_delay();

LCD_PORT->BSRR=(LCD_DB7_BC | LCD_DB6_BC | LCD_DB5_BC | LCD_DB4_BC | LCD_CD_BC | LCD_EN_BC);
LCD_PORT->BSRR=(LCD_DB7_BS);

LCD_PORT->BSRR=LCD_EN_BS;
lcd_delay();
LCD_PORT->BSRR=LCD_EN_BC;
lcd_delay();

}

void lcd_send(uint8_t byte, dat_or_comm dc) {

LCD_PORT->BSRR=(LCD_DB7_BC | LCD_DB6_BC | LCD_DB5_BC | LCD_DB4_BC | LCD_CD_BC | LCD_EN_BC);

if (dc) {
LCD_PORT->BSRR=LCD_CD_BS;
}

if (byte & 0x10) {
LCD_PORT->BSRR=LCD_DB4_BS;
}
if (byte & 0x20) {
LCD_PORT->BSRR=LCD_DB5_BS;
}
if (byte & 0x40) {
LCD_PORT->BSRR=LCD_DB6_BS;
}
if (byte & 0x80) {
LCD_PORT->BSRR=LCD_DB7_BS;
}

LCD_PORT->BSRR=LCD_EN_BS;
lcd_delay();
LCD_PORT->BSRR=LCD_EN_BC;
lcd_delay();


LCD_PORT->BSRR=(LCD_DB7_BC | LCD_DB6_BC | LCD_DB5_BC | LCD_DB4_BC );

if (byte & 0x01) {
LCD_PORT->BSRR=LCD_DB4_BS;
}
if (byte & 0x02) {
LCD_PORT->BSRR=LCD_DB5_BS;
}
if (byte & 0x04) {
LCD_PORT->BSRR=LCD_DB6_BS;
}
if (byte & 0x08) {
LCD_PORT->BSRR=LCD_DB7_BS;
}

LCD_PORT->BSRR=LCD_EN_BS;
lcd_delay();
LCD_PORT->BSRR=LCD_EN_BC;
lcd_delay();


}

#include "stm32F10x.h"

/////should be defined by user /////
#define LCD_PORT GPIOA
#define LCD_CD 2
#define LCD_EN 1
#define LCD_DB4 4
#define LCD_DB5 5
#define LCD_DB6 6
#define LCD_DB7 7
///////////////////////////////////typedef enum {
COMMAND = 0,
DATA = !COMMAND
} dat_or_comm;
typedef enum {
LCD_DISABLE = 0,
LCD_ENABLE = !LCD_DISABLE
} lcd_state;typedef enum {
CURSOR_DISABLE = 0,
CURSOR_ENABLE = !CURSOR_DISABLE
} cursor_state;
typedef enum {
NO_BLINK = 0,
BLINK = !NO_BLINK
} cursor_mode;
#define LCD_EN_BS (1 << LCD_EN)
#define LCD_CD_BS (1 << LCD_CD)
#define LCD_DB4_BS (1 << LCD_DB4)
#define LCD_DB5_BS (1 << LCD_DB5)
#define LCD_DB6_BS (1 << LCD_DB6)
#define LCD_DB7_BS (1 << LCD_DB7)#define LCD_EN_BC (1 << (LCD_EN+16))
#define LCD_CD_BC (1 << (LCD_CD+16))
#define LCD_DB4_BC (1 << (LCD_DB4+16))
#define LCD_DB5_BC (1 << (LCD_DB5+16))
#define LCD_DB6_BC (1 << (LCD_DB6+16))
#define LCD_DB7_BC (1 << (LCD_DB7+16))
#if LCD_EN > 7
#define LCD_EN_H (1 << (LCD_EN-8) * 4)
#define C_LCD_EN_H (7 << ((LCD_EN-8) * 4 + 1))
#else
#define LCD_EN_L (1 << LCD_EN * 4)
#define C_LCD_EN_L (7 << (LCD_EN * 4 + 1))
#endif#if LCD_CD > 7
#define LCD_CD_H (1 << (LCD_CD-8) * 4)
#define C_LCD_CD_H (7 << ((LCD_CD-8) * 4 + 1))
#else
#define LCD_CD_L (1 << LCD_CD * 4)
#define C_LCD_CD_L (7 << (LCD_CD * 4 + 1))
#endif
#if LCD_DB4 > 7
#define DB4_H (1 << (LCD_DB4-8) * 4)
#define C_DB4_H (7 << ((LCD_DB4-8) * 4 + 1))
#else
#define DB4_L (1 << LCD_DB4 * 4)
#define C_DB4_L (7 << (LCD_DB4 * 4 + 1))
#endif#if LCD_DB5 > 7
#define DB5_H (1 << (LCD_DB5-8) * 4)
#define C_DB5_H (7 << ((LCD_DB5-8) * 4 + 1))
#else
#define DB5_L (1 << LCD_DB5 * 4)
#define C_DB5_L (7 << (LCD_DB5 * 4 + 1))
#endif
#if LCD_DB6 > 7
#define DB6_H (1 << (LCD_DB6-8) * 4)
#define C_DB6_H (7 << ((LCD_DB6-8) * 4 + 1))
#else
#define DB6_L (1<< LCD_DB6 * 4)
#define C_DB6_L (7 << (LCD_DB6 * 4 + 1))
#endif#if LCD_DB7 > 7
#define DB7_H (1 << (LCD_DB7-8) * 4)
#define C_DB7_H (7 << ((LCD_DB7-8) * 4 + 1))
#else
#define DB7_L (1 << LCD_DB7 * 4)
#define C_DB7_L (7 << (LCD_DB7 * 4 + 1))
#endif

#ifndef DB4_H
#define DB4_H 0
#endif#ifndef DB5_H
#define DB5_H 0
#endif
#ifndef DB6_H
#define DB6_H 0
#endif#ifndef DB7_H
#define DB7_H 0
#endif
#ifndef DB4_L
#define DB4_L 0
#endif#ifndef DB5_L
#define DB5_L 0
#endif
#ifndef DB6_L
#define DB6_L 0
#endif#ifndef DB7_L
#define DB7_L 0
#endif
#ifndef LCD_CD_L
#define LCD_CD_L 0
#endif#ifndef LCD_CD_H
#define LCD_CD_H 0
#endif
#ifndef LCD_EN_L
#define LCD_EN_L 0
#endif#ifndef LCD_EN_H
#define LCD_EN_H 0
#endif
////////////////////////#ifndef C_DB4_H
#define C_DB4_H 0
#endif
#ifndef C_DB5_H
#define C_DB5_H 0
#endif#ifndef C_DB6_H
#define C_DB6_H 0
#endif
#ifndef C_DB7_H
#define C_DB7_H 0
#endif#ifndef C_DB4_L
#define C_DB4_L 0
#endif
#ifndef C_DB5_L
#define C_DB5_L 0
#endif#ifndef C_DB6_L
#define C_DB6_L 0
#endif
#ifndef C_DB7_L
#define C_DB7_L 0
#endif
#ifndef C_LCD_CD_L
#define C_LCD_CD_L 0
#endif
#ifndef C_LCD_CD_H
#define C_LCD_CD_H 0
#endif#ifndef C_LCD_EN_L
#define C_LCD_EN_L 0
#endif
#ifndef C_LCD_EN_H
#define C_LCD_EN_H 0
#endif#define LCD_PORT_CRH_S (DB4_H | DB5_H | DB6_H | DB7_H | LCD_EN_H | LCD_CD_H)
#define LCD_PORT_CRL_S (DB4_L | DB5_L | DB6_L | DB7_L | LCD_EN_L | LCD_CD_L)
#define LCD_PORT_CRH_C (C_DB4_H | C_DB5_H | C_DB6_H | C_DB7_H | C_LCD_EN_H | C_LCD_CD_H)
#define LCD_PORT_CRL_C (C_DB4_L | C_DB5_L | C_DB6_L | C_DB7_L | C_LCD_EN_L | C_LCD_CD_L)
void lcd_init();
void lcd_send(uint8_t byte, dat_or_comm dc);
void lcd_set_4bit_mode(void);
void lcd_set_state(lcd_state state, cursor_state cur_state, cursor_mode cur_mode);
void lcd_clear(void);
void lcd_out(char * txt);
void lcd_set_xy(uint8_t x, uint8_t y);
void lcd_set_user_char(uint8_t char_num, uint8_t * char_data);
void lcd_delay(void);

вот код который вызывает глюки в отображении:

#include "stm32F10x.h"
#include "hd44780_driver\hd44780_driver.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
int main(void)
{
int x=10000;
int flags=0;
int flags_button=1;
int timer=0,data_out=0;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
 GPIOC->CRH = 0x00000022; // конфигурируем на выход частота 2мгЦ бит 8 и 9

uint8_t user_char[8]; //Сюда будем записывать пользовательский символ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //Вкл порт С
GPIOA->CRH = GPIOA->CRH &~ (1<<0);
while(x)
{
x--;
}
lcd_init(); //Инициализируем дисплей

user_char[0]=0b01110; //А вот тут
user_char[1]=0b10001; // рисуем
user_char[2]=0b10001; // наш символ
user_char[3]=0b10001; //
user_char[4]=0b10001; // Это типа рыба :-)
user_char[5]=0b01010;
user_char[6]=0b10001;
user_char[7]=0b10001;
lcd_set_user_char(0, user_char); // Наша рыба это символ номер ноль

lcd_out("Artos5! TEST"); //Выводм надпись в нулевую строку
lcd_set_xy(0,1); //переводим курсор в первую строку

lcd_out("2014 STM32F100"); //Выводм надпись в нулевую строку
lcd_set_xy(1,1); //переводим курсор в первую строку
lcd_set_state(LCD_ENABLE, CURSOR_DISABLE, NO_BLINK); //Включаем курсор и мигалку
while(1)
{
if(timer==0)
{
	 GPIO_SetBits(GPIOC, GPIO_Pin_8 );
 x=45000;
 while(x)
 {
 x--;
 }
}
if(timer==1)
{
 GPIO_ResetBits(GPIOC, GPIO_Pin_8 );
 x=450000;
 while(x)
 {
 x--;
 }
}
if(timer==2)
{
 GPIO_SetBits(GPIOC, GPIO_Pin_9 );
 x=45000;
 while(x)
 {
 x--;
 }
}
if(timer==3)
{
 GPIO_ResetBits(GPIOC, GPIO_Pin_9 );
 x=450000;
 while(x)
 {
 x--;
 }
}

timer++;
if(timer>3)timer=0;


 if(flags)
 {

 lcd_out("Yarunka lubit "); //Выводм надпись в нулевую строку
 lcd_set_xy(0,1); //переводим курсор в первую строку
 lcd_out("Kolbasu! "); //Выводм надпись в нулевую строку
 lcd_set_xy(1,1); //переводим курсор в первую строку
 lcd_set_state(LCD_ENABLE, CURSOR_DISABLE, NO_BLINK); //Включаем курсор и мигалку
 data_out=0;
 }
 else
 {

 lcd_out("Yarunka ne lubit"); //Выводм надпись в нулевую строку
 lcd_set_xy(0,1); //переводим курсор в первую строку

 lcd_out("Kolbasu! "); //Выводм надпись в нулевую строку
 lcd_set_xy(1,1); //переводим курсор в первую строку
 lcd_set_state(LCD_ENABLE, CURSOR_DISABLE, NO_BLINK); //Включаем курсор и мигалку
 data_out=0;
 }

 if((GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==1) && flags_button==1)
 {

 if(flags)flags=0;
		 else flags=1;
 lcd_clear(); //очищаем дисплей
 data_out=1;
 flags_button=0;
 }
 if((GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0) && flags_button==0)
 {
 flags_button=1;
 }

}
}

а этот код нормально отображает данные на индикаторе:

if(data_out)
{
 if(flags)
 {

 lcd_out("Yarunka lubit "); //Выводм надпись в нулевую строку
 lcd_set_xy(0,1); //переводим курсор в первую строку
 lcd_out("Kolbasu! "); //Выводм надпись в нулевую строку
 lcd_set_xy(1,1); //переводим курсор в первую строку
 lcd_set_state(LCD_ENABLE, CURSOR_DISABLE, NO_BLINK); //Включаем курсор и мигалку
 data_out=0;
 }
 else
 {

 lcd_out("Yarunka ne lubit"); //Выводм надпись в нулевую строку
 lcd_set_xy(0,1); //переводим курсор в первую строку
 //lcd_send(1,DATA); //выводм символ номер ноль
 lcd_out("Kolbasu! "); //Выводм надпись в нулевую строку
 lcd_set_xy(1,1); //переводим курсор в первую строку
 lcd_set_state(LCD_ENABLE, CURSOR_DISABLE, NO_BLINK); //Включаем курсор и мигалку
 data_out=0;
 }
}

в этом коде добавлен флаг с помощью которого данные выводятся только один раз после изменения.

Помогите найти ошибку в коде...... я уже и тайминги менял , и буфер обнулял.. ничего не помогает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
artos5    285

Я очень подозреваю что индикатор так ведет себя из за этой функции:

void lcd_set_xy(uint8_t x, uint8_t y)  {
if (y==0) {
lcd_send( ((1<<7) | (x)),COMMAND);
} else {
lcd_send( ((3<<6) | (x)),COMMAND);
}
}

Я не понимаю как работает эта строчка:

lcd_send( ((3<<6) | (x)),COMMAND);

Посмотрел это видео:

Блин... у меня тот же глюк.... Только мусор другой . И через раз инициализируется после сброса...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

Уважаемые форумчане! Заметил такую особенность:

Если перед выводом данных очищать индикатор - то выводятся данные корректно! Но индикатор мерцает!

Как исправить эту проблему?

Мне надо постоянно слать данные без очистки содержимого на экране!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
swat24    9

Пока не вдавался в подробности библиотеки, но глюки, обычно, бывают из-за не правильных таймингов. Попробуйте увеличить время ожидания между отправками.

На счет очистки - если новые данные по количеству символов одинаковые с уже показанной строкой, то должно работать нормально. Просто перезапишется и все. Но если строка меньше, чем была, то или нужна очистка или дополнить строку дополнительными пробелами, для очистки неиспользуемых знакомест.

Я вроде дополнял строку доп. пробелами. т.к. очищать весь экран мне не надо было (изменял только значения параметров, а названия оставались не тронутыми).

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

Спасибо что обратили внимание на тему.

Я попробовал так:

без очистки экрана выводить данные по нажатию на кнопку.

Получил вообще страшный глюк.........

Глюк такой:

первая строка которая отображалась до вечного цикла (то есть: "Artos5! TEST") осталась!

а на второй строке высвечивается содержимое второй строки + накладывается содержимое (которое я пытаюсь отправить в первую строку) только обрезается содержимым второй строки........... короче колбаса какая то!!! :))))

Выкинул нафик исходник!!! Пилю теперь этот пример: http://avrlab.com/node/80

Очень нравится стиль написания. Очень понятный для меня.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
swat24    9

Я так делал :

#include "hd44780.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx.h"
#include "Delay.h"

uint16_t d7 = GPIO_Pin_10;
uint16_t d6 = GPIO_Pin_11;
uint16_t d5 = GPIO_Pin_12;
uint16_t d4 = GPIO_Pin_13;
uint16_t rs = GPIO_Pin_8;
uint16_t en1 = GPIO_Pin_7;
uint16_t en2 = GPIO_Pin_9;

const char LCD_Char[65]={'A', 0xA0,'B',0xA1,0xE0, 'E',0xA3,0xA4,0xA5,0xA6, 'K',0xA7, 'M', 'H', 'O',0xA8,
   'P', 'C', 'T',0xA9,0xAA, 'X',0xE1,0xAB,0xAC,0xE2,0xAD,0xAE, 'b',0xAF,0xB0,0xB1,
   'a',0xB2,0xB3,0xB4,0xE3, 'e',0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD, 'o',0xBE,
   'p', 'c',0xBF, 'y',0xE4, 'x',0xE5,0xC0,0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7};


void lcd_delay(void) {
uDelay(25);
}

void Lcd_Write(int Data)
{
GPIOD->ODR = Data;
GPIO_SetBits(GPIOC, en1);
GPIO_ResetBits(GPIOC, en1);
GPIO_SetBits(GPIOC, en2);
GPIO_ResetBits(GPIOC, en2);
}

void lcd_init() {
GPIO_InitTypeDef gpio;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
gpio.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpio.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &gpio);

gpio.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_Init(GPIOC, &gpio);
//delay(0xffFFF);
mDelay(15);

//GPIOD->ODR = 12288;
Lcd_Write(12288);
//delay(0xFFF);
mDelay(4);

Lcd_Write(12288);
//delay(0xFFF);
uDelay(100);

Lcd_Write(12288);
//delay(0xFFF);
uDelay(100);

Lcd_Write(4096);
//delay(0xFFF);
uDelay(100);

Lcd_Write(4096);
Lcd_Write(1024);
//delay(0xFFF);
uDelay(100);


Lcd_Write(0);
Lcd_Write(6144);
//delay(0xFFF);
uDelay(100);

Lcd_Write(0);
Lcd_Write(3072);
//delay(0xFFF);
uDelay(100);

Lcd_Write(0);
Lcd_Write(8192);
//delay(0xFFF);
uDelay(100);
}

void lcd_set_user_char(uint8_t char_num, uint8_t * char_data) {
uint8_t i;
lcd_send(((1<<6) | (char_num * 8) ), COMMAND,0);
for (i=0;i<=7;i++) {
lcd_send(char_data[i],DATA,0);
}
lcd_send((1<<7), COMMAND,0);
}

void lcd_text(char * txt,u8 x, u8 y) {
if (y<2){
if (y==0) {
lcd_send( ((1<<7) | (x)),COMMAND,y);
} else {
lcd_send( ((3<<6) | (x)),COMMAND,y);
}
while(*txt) {
if (*txt>=0xc0)
{
*txt=LCD_Char[*txt-0xc0];
} 
lcd_send(*txt,DATA,y);
txt++;
}
}else
{
if (y==2) {
lcd_send( ((1<<7) | (x)),COMMAND,y);
} else {
lcd_send( ((3<<6) | (x)),COMMAND,y);
}
while(*txt) {
if (*txt>=0xc0)
{
*txt=LCD_Char[*txt-0xc0];
} 
lcd_send(*txt,DATA,y);
txt++;
}
}
}

void lcd_clear(void) {
lcd_send(0x01,COMMAND,0);
lcd_send(0x01,COMMAND,3);
}

void lcd_set_state(lcd_state state, cursor_state cur_state, cursor_mode cur_mode)  {
if (state==LCD_DISABLE)  {
lcd_send(0x08,COMMAND,0);
} else {
if (cur_state==CURSOR_DISABLE) {
if (cur_mode==NO_BLINK)  {
lcd_send(0x0C,COMMAND,0);
} else {
lcd_send(0x0D,COMMAND,0);
}
} else  {
if (cur_mode==NO_BLINK)  {
lcd_send(0x0E,COMMAND,0);
} else {
lcd_send(0x0F,COMMAND,0);
}
}
}
}



void lcd_send(uint8_t byte, dat_or_comm dc, uint8_t rows)  {
if (rows==0||rows==1)
{

GPIO_ResetBits(GPIOD, GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 );
//LCD_PORT->BSRR=(LCD_DB7_BC | LCD_DB6_BC | LCD_DB5_BC | LCD_DB4_BC) ;
GPIO_ResetBits(GPIOC, rs | en1 | en2 );
//LCD_PORT->BSRR=(RS|EN1|EN2);

if (dc) {
GPIO_SetBits(GPIOC, rs);
//LCD_PORT->BSRR=LCD_CD_BS;
}

if (byte & 0x10) {
GPIO_SetBits(GPIOD, d4);
//LCD_PORT->BSRR=LCD_DB4_BS;
}
if (byte & 0x20) {
GPIO_SetBits(GPIOD, d5);
//LCD_PORT->BSRR=LCD_DB5_BS;
}
if (byte & 0x40) {
GPIO_SetBits(GPIOD, d6);
//LCD_PORT->BSRR=LCD_DB6_BS;
}
if (byte & 0x80) {
GPIO_SetBits(GPIOD, d7);
//LCD_PORT->BSRR=LCD_DB7_BS;
}

GPIO_SetBits(GPIOC, en1);

//LCD_PORT->BSRR=LCD_EN_BS;
lcd_delay(); 
GPIO_ResetBits(GPIOC, en1);

//LCD_PORT->BSRR=LCD_EN_BC;
lcd_delay();


GPIO_ResetBits(GPIOD, GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 );
//LCD_PORT->BSRR=(LCD_DB7_BC | LCD_DB6_BC | LCD_DB5_BC | LCD_DB4_BC) ;

if (byte & 0x01) {
GPIO_SetBits(GPIOD, d4);
//LCD_PORT->BSRR=LCD_DB4_BS;
}
if (byte & 0x02) {
GPIO_SetBits(GPIOD, d5);
//LCD_PORT->BSRR=LCD_DB5_BS;
}
if (byte & 0x04) {
GPIO_SetBits(GPIOD, d6);
//LCD_PORT->BSRR=LCD_DB6_BS;
}
if (byte & 0x08) {
GPIO_SetBits(GPIOD, d7);
//LCD_PORT->BSRR=LCD_DB7_BS;
}

GPIO_SetBits(GPIOC, en1);
//LCD_PORT->BSRR=LCD_EN_BS;
lcd_delay();
GPIO_ResetBits(GPIOC, en1);
//LCD_PORT->BSRR=LCD_EN_BC;
lcd_delay();
}

if (rows==2||rows==3)
{

GPIO_ResetBits(GPIOD, GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 );
//LCD_PORT->BSRR=(LCD_DB7_BC | LCD_DB6_BC | LCD_DB5_BC | LCD_DB4_BC) ;
GPIO_ResetBits(GPIOC, rs | en1 | en2 );
//LCD_PORT->BSRR=(RS|EN1|EN2);

if (dc) {
GPIO_SetBits(GPIOC, rs);
//LCD_PORT->BSRR=LCD_CD_BS;
}

if (byte & 0x10) {
GPIO_SetBits(GPIOD, d4);
//LCD_PORT->BSRR=LCD_DB4_BS;
}
if (byte & 0x20) {
GPIO_SetBits(GPIOD, d5);
//LCD_PORT->BSRR=LCD_DB5_BS;
}
if (byte & 0x40) {
GPIO_SetBits(GPIOD, d6);
//LCD_PORT->BSRR=LCD_DB6_BS;
}
if (byte & 0x80) {
GPIO_SetBits(GPIOD, d7);
//LCD_PORT->BSRR=LCD_DB7_BS;
}

GPIO_SetBits(GPIOC, en2);
//LCD_PORT->BSRR=LCD_EN_BS;
lcd_delay();
GPIO_ResetBits(GPIOC, en2);
//LCD_PORT->BSRR=LCD_EN_BC;
lcd_delay();


GPIO_ResetBits(GPIOD, GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 );
//LCD_PORT->BSRR=(LCD_DB7_BC | LCD_DB6_BC | LCD_DB5_BC | LCD_DB4_BC) ;

if (byte & 0x01) {
GPIO_SetBits(GPIOD, d4);
//LCD_PORT->BSRR=LCD_DB4_BS;
}
if (byte & 0x02) {
GPIO_SetBits(GPIOD, d5);
//LCD_PORT->BSRR=LCD_DB5_BS;
}
if (byte & 0x04) {
GPIO_SetBits(GPIOD, d6);
//LCD_PORT->BSRR=LCD_DB6_BS;
}
if (byte & 0x08) {
GPIO_SetBits(GPIOD, d7);
//LCD_PORT->BSRR=LCD_DB7_BS;
}

GPIO_SetBits(GPIOC, en2);
//LCD_PORT->BSRR=LCD_EN_BS;
lcd_delay();
GPIO_ResetBits(GPIOC, en2);
//LCD_PORT->BSRR=LCD_EN_BC;
lcd_delay();
}
}

Изменено пользователем swat24

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

Это просто кАшмар какой то :))

Переделал код под СТМ32 из этой статьи: http://avrlab.com/node/80

#include "stm32F10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#define RS 2	    // управляющие константы
#define E  3	    // управляющие константы
#define RS_S  GPIO_SetBits(GPIOA, GPIO_Pin_2 );	  //RS - установить сигнал управления ЖКИ
#define RS_R  GPIO_ResetBits(GPIOA, GPIO_Pin_2 );	  //RS  - сбросить сигнал управления ЖКИ
#define E_S  GPIO_SetBits(GPIOA, GPIO_Pin_1 );	    //E  - установить сигнал управления ЖКИ
#define E_R  GPIO_ResetBits(GPIOA, GPIO_Pin_1 );	    //E  - сбросить сигнал управления ЖКИ
#define BIT_4S  GPIO_SetBits(GPIOA, GPIO_Pin_4 );
#define BIT_5S  GPIO_SetBits(GPIOA, GPIO_Pin_5 );
#define BIT_6S  GPIO_SetBits(GPIOA, GPIO_Pin_6 );
#define BIT_7S  GPIO_SetBits(GPIOA, GPIO_Pin_7 );
#define BIT_4R  GPIO_ResetBits(GPIOA, GPIO_Pin_4 );
#define BIT_5R  GPIO_ResetBits(GPIOA, GPIO_Pin_5 );
#define BIT_6R  GPIO_ResetBits(GPIOA, GPIO_Pin_6 );
#define BIT_7R  GPIO_ResetBits(GPIOA, GPIO_Pin_7 );
#define TIME 1000	 //Константа временной задержки для ЖКИ
  //Частота тактирование МК - 4Мгц
uint8_t data_port=0;
//Программа формирвоания задержки
void pause (unsigned long int a)
{ unsigned long int i;
 for (i=a;i>0;i--);
 for (i=a;i>0;i--);
}
void data_out()
{
if ((data_port&0x04)==0x04) //RS
{
RS_S;
GPIO_SetBits(GPIOC, GPIO_Pin_8 );
}
else
{
RS_R;
GPIO_ResetBits(GPIOC, GPIO_Pin_8 );
}
if ((data_port&0x08)==0x08) //E
{
E_S;
GPIO_SetBits(GPIOC, GPIO_Pin_9 );
}
else
{
RS_R;
GPIO_ResetBits(GPIOC, GPIO_Pin_9 );
}
if ((data_port&0x10)==0x10) // bit4
{
BIT_4S;
}
else
{
BIT_4R;
}
if ((data_port&0x20)==0x20) // bit5
{
BIT_5S;
}
else
{
BIT_5R;
}
if ((data_port&0x40)==0x40) // bit6
{
BIT_6S;
}
else
{
BIT_6R;
}
if ((data_port&0x80)==0x80) // bit7
{
BIT_7S;
}
else
{
BIT_7R;
}
}
//Программа передачи команд в ЖКИ
void lcd_com (unsigned char lcd)
{ unsigned char temp;

 temp=(lcd&~(1<<RS))|(1<<E);  //RS=0 – это команда
 data_port=temp;						 //Выводим на portD старшую тетраду команды, сигналы RS, E
 data_out();
 pause(3000);						 //Небольшая задержка в 1 такт МК, для стабилизации
 data_port=temp&~(1<<E);				 //Сигнал записи команды
 data_out();
 temp=((lcd<<4)&~(1<<RS))|(1<<E); //RS=0 – это команда
 data_port=temp;						 //Выводим на portD младшую тетраду команды, сигналы RS, E
 data_out();
 pause(3000);						 //Небольшая задержка в 1 такт МК, для стабилизации
 data_port=temp&~(1<<E);				 //Сигнал записи команды
 data_out();
 pause (10*TIME);				 //Пауза для выполнения команды
 GPIO_ResetBits(GPIOC, GPIO_Pin_9 );
}
//Программа записи данных в ЖКИ
void lcd_dat (unsigned char lcd)
{ unsigned char temp;

 temp=(lcd|(1<<RS))|(1<<E);  //RS=1 – это данные
 data_port=temp;						 //Выводим на portD старшую тетраду данных, сигналы RS, E
 data_out();
 pause(3000);				  //Небольшая задержка в 1 такт МК, для стабилизации
 data_port=temp&~(1<<E);				 //Сигнал записи данных
 data_out();
 temp=((lcd<<4)|(1<<RS))|(1<<E); //RS=1 – это данные
 data_port=temp;						 //Выводим на portD младшую тетраду данных, сигналы RS, E
 data_out();
 pause(3000);						 //Небольшая задержка в 1 такт МК, для стабилизации
 data_port=temp&~(1<<E);				 //Сигнал записи данных
 data_out();
 pause(TIME);						 //Пауза для вывода данных

}
//Программа иниализации ЖКИ
void lcd_init (void)
{
lcd_com(0x2c);  //4-проводный интерфейс, 5x8 размер символа
pause(1000*TIME);
lcd_com(0x0c);  //Показать изображение, курсор не показывать
pause(1000*TIME);
lcd_com(0x01);  //Очистить DDRAM и установить курсор на 0x00
pause (1000*TIME);
}
//Основная программа
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //Вкл порт
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //Вкл порт
GPIOC->CRL=0x22222222;
GPIOC->CRH=0x22222222;
GPIOA->CRL=0x22222222;
GPIOA->CRH=0x22222222;
pause(30000); //Задержка, чтобы ЖКИ успел включиться
lcd_init(); //Инициализация ЖКИ

lcd_dat('w');   //Вывод "www.avrlab.com"
lcd_dat('w');
lcd_dat('w');
lcd_dat('.');
lcd_dat('a');
lcd_dat('v');
lcd_dat('r');
lcd_dat('l');
lcd_dat('a');
lcd_dat('b');
lcd_dat('.');
lcd_dat('c');
lcd_dat('o');
lcd_dat('m');
lcd_com(0xc0); //Ставим курсор на начало 2-й строки ЖКИ
lcd_dat('I'); //Записываем "It's so easy"
lcd_dat('t');
lcd_dat('"');
lcd_dat('s');
lcd_dat(' ');
lcd_dat('s');
lcd_dat('o');
lcd_dat(' ');
lcd_dat('e');
lcd_dat('a');
lcd_dat('s');
lcd_dat('y');

while(1) //бесконечный цикл
;
}

индикатор даже не инициализируется ........ что я не так сделал? Я уже на гране взрыва :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

Проблема решена!!!! И заодно переписана библиотека :)

весь косяк был в установке курсора!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

Вот моя библиотека:

lib_HD44780.rar

Из особенностей:

можно прикрутить к дисплею любую ножку МК! Хоть из разных портов!

Пример использования:

lcd_init(); //Инициализация ЖКИ

kursor_set(LCD_ENABLE, CURSOR_DISABLE, NO_BLINK);
lcd_clear();


lcd_xy(0,0);

lcd_out("2014");

lcd_xy(1,0); //Ставим курсор на начало 2-й строки ЖКИ

lcd_out("Artos5!!!!");

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ZERRO_    1

artos5 у меня дисплей wh1202a что-то нужно еще поменять в вашей библиотеке кроме распиновки ножек? Может я неправильно подключаю библиотеку, как ее подключить? Никак не удается добиться от этого дисплея хоть чего-то, помогите пожалуйста.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

Сейчас дам более усовершенствованную библиотеку и опишу подробно как подключить.

Какая среда разработки и какой МК у Вас?

Для использования , нужно файлы подключить к проекту. И подключить библиотеку в исходном коде.

//В хедере нужно с конфигурировать порты
// К примеру так:

#define RS_S GPIO_SetBits(GPIOA, GPIO_Pin_2 ); //RS - установить сигнал управления ЖКИ
#define RS_R GPIO_ResetBits(GPIOA, GPIO_Pin_2 ); //RS - сбросить сигнал управления ЖКИ

#define E_S GPIO_SetBits(GPIOA, GPIO_Pin_1 ); //E - установить сигнал управления ЖКИ
#define E_R GPIO_ResetBits(GPIOA, GPIO_Pin_1 ); //E - сбросить сигнал управления ЖКИ

#define BIT_4S GPIO_SetBits(GPIOA, GPIO_Pin_4 );
#define BIT_5S GPIO_SetBits(GPIOA, GPIO_Pin_5 );
#define BIT_6S GPIO_SetBits(GPIOA, GPIO_Pin_6 );
#define BIT_7S GPIO_SetBits(GPIOA, GPIO_Pin_7 );

#define BIT_4R GPIO_ResetBits(GPIOA, GPIO_Pin_4 );
#define BIT_5R GPIO_ResetBits(GPIOA, GPIO_Pin_5 );
#define BIT_6R GPIO_ResetBits(GPIOA, GPIO_Pin_6 );
#define BIT_7R GPIO_ResetBits(GPIOA, GPIO_Pin_7 );

Пользоваться библиотекой так:

#include <stdio.h>
#include "hd44780_driver.h"
void main(void)
{
lcd_init();
lcd_clear();
lcd_xy(0, 1) ; // выводить будем в верхнюю строку во вторую позицию
lcd_out("Hello world"); // выводим строку
//или так:
sprintf(buff, "%dV" , data_adc); // выводим переменную
lcd_xy(0, 1) ;
lcd_out(buff);
while(1);
}

Также, надо подправить функцию lcd_init(); если будете использовать другой МК или среду.

hd44780_driver_by_Artos.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ZERRO_    1

У меня stm32f103cbt6, среда разработки CoIDE. Буду пробовать) Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

Возможно понадобится вам подправить задержки. Для этого нужно подправить константу в библиотеке.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

У меня stm32f103cbt6. Спасибо.

Удалось победить дисплей? :)

Попробуйте пожалуйста подключить порты и ножки ЖКИ в разнобой .

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ZERRO_    1

Увы нет( Что ни делаю - две строчки черных квадратиков и все. Сижу разбираюсь с таймингами....

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

Должна быть одна. Может у вас дисплей труп?

Попробуйте все тайминги увеличить в три раза.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ZERRO_    1

Сразу одна, после ресет - две, это значит что он прошел инициализацию? Сейчас попробую...

Нет, увеличение таймингов ничего не меняет.

Изменено пользователем ZERRO_

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

Что то подсказывает мне что где то или непропай , или битый дисплей, или неверная конфигурация . У меня все работает. Сегодня специально попробую настроить на разные порты.

Вот: http://cs618031.vk.me/v618031496/e1ae/nK3myRW_uZY.jpg

А вечером попробую на разные порты привязать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

после ресет - две, это значит что он прошел инициализацию?

Да, инициализацию проходит значит. Вы библиотеку тщательно осматривали внутри? Все параметры "подправили"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
КЭС    974

Ко

Сразу одна, после ресет - две

Контраст не перекручен?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ZERRO_    1

Попробовал подключить дисплей к atmega он работает, выставил яркость. На stm32 оказалось он ничего не показывал (я и в правду перекручивал яркость). Хочу попробывать подключить другую библиотеку из примеров CoIDE но ошибка error: ld returned 1 exit status , multiple definition of `DelayMs'. Не могу разобраться... не думал что столько проблем будет с дисплеем, наверное у меня плохая карма)

lcd_c.txt

lcd_h.txt

main.txt

Изменено пользователем ZERRO_

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

Подключил так порты:

#define RS_S  GPIO_SetBits(GPIOA, GPIO_Pin_11 );	  //RS - установить сигнал управления ЖК�
#define RS_R  GPIO_ResetBits(GPIOA, GPIO_Pin_11 );	  //RS  - сбросить сигнал управления ЖК�
#define E_S  GPIO_SetBits(GPIOA, GPIO_Pin_12 );	    //E  - установить сигнал управления ЖК�
#define E_R  GPIO_ResetBits(GPIOA, GPIO_Pin_12 );	    //E  - сбросить сигнал управления ЖК�
#define BIT_4S  GPIO_SetBits(GPIOC, GPIO_Pin_6 );
#define BIT_5S  GPIO_SetBits(GPIOA, GPIO_Pin_8 );
#define BIT_6S  GPIO_SetBits(GPIOA, GPIO_Pin_9 );
#define BIT_7S  GPIO_SetBits(GPIOA, GPIO_Pin_10 );
#define BIT_4R  GPIO_ResetBits(GPIOC, GPIO_Pin_6 );
#define BIT_5R  GPIO_ResetBits(GPIOA, GPIO_Pin_8 );
#define BIT_6R  GPIO_ResetBits(GPIOA, GPIO_Pin_9 );
#define BIT_7R  GPIO_ResetBits(GPIOA, GPIO_Pin_10 );

Работает всё супер! Так что мое предположение о всевозможной конфигурации подтвердилось :)

Править надо в двух местах библиотеку:

#define RS_S  GPIO_SetBits(GPIOA, GPIO_Pin_11 );	  //RS - установить сигнал управления ЖК�
#define RS_R  GPIO_ResetBits(GPIOA, GPIO_Pin_11 );	  //RS  - сбросить сигнал управления ЖК�
#define E_S  GPIO_SetBits(GPIOA, GPIO_Pin_12 );	    //E  - установить сигнал управления ЖК�
#define E_R  GPIO_ResetBits(GPIOA, GPIO_Pin_12 );	    //E  - сбросить сигнал управления ЖК�
#define BIT_4S  GPIO_SetBits(GPIOC, GPIO_Pin_6 );
#define BIT_5S  GPIO_SetBits(GPIOA, GPIO_Pin_8 );
#define BIT_6S  GPIO_SetBits(GPIOA, GPIO_Pin_9 );
#define BIT_7S  GPIO_SetBits(GPIOA, GPIO_Pin_10 );
#define BIT_4R  GPIO_ResetBits(GPIOC, GPIO_Pin_6 );
#define BIT_5R  GPIO_ResetBits(GPIOA, GPIO_Pin_8 );
#define BIT_6R  GPIO_ResetBits(GPIOA, GPIO_Pin_9 );
#define BIT_7R  GPIO_ResetBits(GPIOA, GPIO_Pin_10 );

и еще тут:

void lcd_init (void)
......

Если немного дописать библу - то можно сделать что править придется только в хедере.

Попробовал подключить дисплей....

Вы мою библиотеку пробовали подключать? Прикрепленные файлы не являются моей библиотекой.

Если пробовали - код в студию. И будем разбираться почему не работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
artos5    285

Попробуйте так:

void lcd_init (void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIOB->CRL=0x44422422; //OUT push-pull 2MHz
GPIOB->CRH=0x44444422;
.......

А напомните какой у Вас МК? Может шина не та выбрана при включении тактирования порта?

У меня сейчас на системнике лежит отладка с дисплеем , и работает :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ваша публикация должна быть проверена модератором

Гость
Вы не авторизованы. Если у вас есть аккаунт, пожалуйста, войдите.
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Восстановить форматирование

  Разрешено не более 75 смайлов.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

Загрузка...

  • Сообщения

    • спасибо за комент! дошел  до кода  с компарированием   
    • @Dr. West , Если вы знаете более компактный аналог WS2812 - можно рассмотреть.
      Но я к сожалению таких не знаю.
      У меня между стенкой корпуса (на которой будет лого) и платой около 6 мм.
      Размер корпуса WS2812 примерно 5x5x1.6 мм.
      Боком его конечно можно поставить, но с трудом, ибо будет мешать плате сам светодиод и кусок оргстекла в 5 мм толщиной.
      Потому надо либо срезать бока корпуса WS2812 (к чему прибегать вообще не хочу, да и сточить получится без повреждений максимум 1 мм), либо искать более миниатюрный аналог...
    • Тогда очень странно, что вы не понимаете очевидных вещей: 1. Конструкция существующих  пилотов очень проста и потому надёжна (явное некачественное фуфло не рассматриваем). А также дёшева и технологична. Там всё на своём месте - ни убавить, ни прибавить. Модульно - кассетная же конструкция сразу резко увеличит стоимость и, одновременно, снизит надёжность, как механическую, так и электрическую. 2. Большинству потребителей нафиг не надо собирать какой-то там непонятный конструктор, он в этом не разбирается, ему нужен просто удлиннитель с N-ным количеством розеток и, желательно, подешевле. Благо выбор на рынке есть на любой вкус и кошелёк. 3. Универсальный мультитул "на все случаи жизни" всегда менеее удобен и стоит дороже, чем специализированный инструмент для одной операции. Т.е. на вопросы "Чем изобретение лучше существующих аналогов" и "Кому это надо" убедительных ответов нет. Итого - ваша задумка и есть то самое ведро для сортира, да ещё и телескопически раздвигающееся - в зависимости от потребного объема.
    • У дисплеев засветка идёт за счёт рассеивания в толще материала. Т.е. светодиод светит в торец листа пластика. Рассмотрите этот вариант.
    • Желательно чтоб ресурсов МК хватало для редкой смены цвета одного светодиода WS2812...
    • @Dr. West , на расстоянии не получится, в корпусе места едва ли на светодиод хватит...
      Ну и потом, в дисплеях типа 1602 светодиод с рассеивателем одно целое, никаких расстояний нет, и засветка довольно равномерная. Сам пользовался таким дисплеем, и знаю что говорю )
      Да и по фото во вложении места раз в 5 меньше в том месте, а ведь работает тоже без расстояний ) Пластик от подсветки мониторов вроде как оргстекло, есть у меня кусочек, но он по толщине не равномерен (), и раза в два-три толще чем удастся уместить...