Вопросы по программированию стенда SDK-2.0

Учебный лабораторный комплекс SDK-2.0 на базе микроконтроллера LPC2292 с ядром ARM7TDMI-S # CAN 2.0, RS-485, RS-232, Ethernet 10/100Base-TX, IEEE 802.15.4 (ZigBee)

Re: Утилиты для программирования стенда SDK-2.0

Сообщение pavo_lusa » 03 ноя 2008, 22:38

bmig писал(а):Спасибо сегодня попробую.

Да, на глаза попалась книга по программированию микроконтроллеров серии LPC2000
(название книги напишу по позже):

}


А не могли ли Вы открыть секрет, как называется книга ???
Спасибо!
pavo_lusa
 
Сообщения: 13
Зарегистрирован: 03 ноя 2008, 21:22

Re: Вопросы по программированию стенда SDK-2.0

Сообщение invaisor » 03 ноя 2008, 22:44

pavo_lusa писал(а):Доброго времени суток...ребята мож объяснить, в примере led_line, что делают инструкция val<<=20; и инструкция return;
вот кусок кода:
void led_mode(unsigned int val)
{
val <<= 20;
if (val > 3) return;
IOCLR2 = 0x00300000;
IOSET2 |= val;
}


Во-первых там немного другой код -
Код: Выделить всё
void led_mode(unsigned int val)
{
   if (val > 3) return;
   val <<= 20;
   IOCLR2 = 0x00300000;
   IOSET2 |= val;
}


Смысл return в том, что допутимыми значениями для val являются - 0(светодиоды не включены), 1(можно управлять младшими 4 штуками), 2(старшими 4 штуками) и 3(управление и младшей 4 и старшей четверкой).
Т.е. на SDK-2.0 управление светодиодами сделано так: мы можем зажигать либо светодиоды из младшей 4-ки, либо старшей 4-ке или из той и с другой, но только аналогичные (к примеру 1 и 2 светодиод на 4 младших и 4 старших, но нельзя на 4 младших 2 и 3 светодиод, а на 4 старших 1 и 2, хотя можно просто быстро переключать режим :smile: , но яркость из-за этого упадет)

val <<= 20; - это сдвиг значения val на 20 битов влево, т.е. если val = 0x0000000X, то после сдвига val = 0x00X00000. Это сделано потому, что 20 и 21 бит порта P2 управляет режимом, о котором я говорил в начале поста.
Аватара пользователя
invaisor
 
Сообщения: 227
Зарегистрирован: 08 апр 2008, 16:08

Re: Утилиты для программирования стенда SDK-2.0

Сообщение invaisor » 03 ноя 2008, 22:57

pavo_lusa писал(а):А не могли ли Вы открыть секрет, как называется книга ???
Спасибо!

Тот секрет я не раскрою, ибо сам не знаю :(
Но если посоветовать, то
  • Для фундаментальных знаний, что-нибудь про архитектуру ARM в общем, типа ARM System-on-Chip Architecture (2nd Edition) by Steve Furber
  • Рукодство пользователя LPC2292
  • Посетить ( http://www.nxp.com/#/pip/pip=[pip=LPC2292_2294_6]|pp=[t=pip,i=LPC2292_2294_6] ) сайт LPC2292[/url] где очень много документации в том числе и application notes, т.е. те же примеры программирования

Предположения насчет книги:
Редькин П.П. Микроконтроллеры ARM7. Семейство LPC2000. Руководство пользователя (есть и отсканенный вариант в сети)
Аватара пользователя
invaisor
 
Сообщения: 227
Зарегистрирован: 08 апр 2008, 16:08

Re: Вопросы по программированию стенда SDK-2.0

Сообщение pavo_lusa » 04 ноя 2008, 18:55

спасибо!
pavo_lusa
 
Сообщения: 13
Зарегистрирован: 03 ноя 2008, 21:22

Re: Вопросы по программированию стенда SDK-2.0

Сообщение pavo_lusa » 04 ноя 2008, 19:10

ещё не отвечали, что делает инструкция return.
пожалуйста не ругайте меня за глупые вопросы! я новичок.

void led_mode(unsigned int val)
{
if (val > 3) return;
val <<= 20;
IOCLR2 = 0x00300000;
IOSET2 |= val;
}

Спасибо !
pavo_lusa
 
Сообщения: 13
Зарегистрирован: 03 ноя 2008, 21:22

Re: Вопросы по программированию стенда SDK-2.0

Сообщение invaisor » 04 ноя 2008, 21:04

pavo_lusa писал(а):ещё не отвечали, что делает инструкция return.
пожалуйста не ругайте меня за глупые вопросы! я новичок.

void led_mode(unsigned int val)
{
if (val > 3) return;
val <<= 20;
IOCLR2 = 0x00300000;
IOSET2 |= val;
}


Если значение val больше 3, то выполнение функции прекращается, происходит возврат из функции.
Если значение val равно или меньше 3, то выполнение функции продолжается.
return это команда возврата, причем в данном случае никакое значение не возвращается.

Вообще я думаю для дальнейшего понимания кода стоило бы почитать что-нибудь про язык Си. Вроде "Керниган, Пайк. Язык программирования Си".
Аватара пользователя
invaisor
 
Сообщения: 227
Зарегистрирован: 08 апр 2008, 16:08

Re: Вопросы по программированию стенда SDK-2.0

Сообщение pavo_lusa » 05 ноя 2008, 10:47

ага! всё понятно.
Спасибо Вам за хороший совет.
pavo_lusa
 
Сообщения: 13
Зарегистрирован: 03 ноя 2008, 21:22

Re: Вопросы по программированию стенда SDK-2.0

Сообщение OYTIS » 19 мар 2009, 18:24

Прошу совета!
Пытаюсь в целях отладки добавить вывод информации на UART.
Код: Выделить всё
init_pio()
{
    PINSEL0 = 0x80550055;
.....}
init_serial0()
{
    U0LCR   = 0x83;
    U0DLL   = 78;           
    U0DLM   = 0x00;
    U0LCR   = 0x03;
}
void main(void)
{
    init_pio();
    init_serial0();         
    wsio0('a');
    wsio0('\n');
    wsio0('b');
    type("\n [MAIN] Start");
    .....
    while(1);
}

На выходе (терминал lpc2k_pgm частотой 9600) - ничего, кроме сообщений самого lpc2k_pgm. Но если поместить вывод на UART в цикл ( while(1){type("\n [MAIN] Start")} ), данные на терминал исправно поступают. В чем тут может быть проблема, на что стоит обратить внимание?
OYTIS
 
Сообщения: 76
Зарегистрирован: 22 апр 2008, 12:11

Re: Вопросы по программированию стенда SDK-2.0

Сообщение Интегральный вычислитель » 19 мар 2009, 18:46

OYTIS писал(а):На выходе (терминал lpc2k_pgm частотой 9600) - ничего, кроме сообщений самого lpc2k_pgm. Но если поместить вывод на UART в цикл ( while(1){type("\n [MAIN] Start")} ), данные на терминал исправно поступают. В чем тут может быть проблема, на что стоит обратить внимание?

'a' и 'b' тоже не выводятся?
Попробуйте другой терминал.
I Have Seen The Truth And It Doesn't Make Any Sense
Аватара пользователя
Интегральный вычислитель
 
Сообщения: 561
Зарегистрирован: 02 апр 2008, 16:04
Откуда: из Леса

Re: Вопросы по программированию стенда SDK-2.0

Сообщение invaisor » 19 мар 2009, 20:33

OYTIS писал(а):В чем тут может быть проблема, на что стоит обратить внимание?

Без полных исходников всего, что прямо или косвенно относится к выводу по UART очень трудно определить в чем может заключаться проблема. Хотя бы взглянуть на то, что есть wsio0 и type.

Интегральный вычислитель писал(а):'a' и 'b' тоже не выводятся?

Присоединяюсь к вопросу.
Если они выводяться, а type ничего не выводит, тогда все ясно. Значит надо смотреть в сторону setvbuf, т.е. по умолчанию type использует буферизацию вывода (Full buffering или Line buffering), поступление символа переноса строки заставляет его опустошить буфер и физически передать данные. Все что надо сделать, это скорее всего установить у stdout тип буферизации в No buffering.
Аватара пользователя
invaisor
 
Сообщения: 227
Зарегистрирован: 08 апр 2008, 16:08

Re: Вопросы по программированию стенда SDK-2.0

Сообщение OYTIS » 19 мар 2009, 21:26

Да, конечно. Я, видимо, был слишком удручен происходящим =)
Код: Выделить всё
unsigned char wsio0( unsigned char ch ) 
{         
    while ( ! ( U0LSR & 0x20 ) );
    U0THR = ch;

    return OK;
}

void type( char * s )
{
    while ( *s )
        wsio0( *s++ );
}


Никаких буферов здесь не используется, все непосредственно через UART. 'a' и 'b' вне цикла тоже не выводятся, а если в цикле - выводятся на терминал "битыми"(в виде знаков вопроса), что, безусловно, добавляет происходящему загадочности. Строки в цикле выводятся нормально.
OYTIS
 
Сообщения: 76
Зарегистрирован: 22 апр 2008, 12:11

Re: Вопросы по программированию стенда SDK-2.0

Сообщение invaisor » 19 мар 2009, 23:05

Еще один вопрос - какой компилятор(среду разработки) вы используете? (Keil, GNUARM или что-то еще)
Аватара пользователя
invaisor
 
Сообщения: 227
Зарегистрирован: 08 апр 2008, 16:08

Re: Вопросы по программированию стенда SDK-2.0

Сообщение OYTIS » 20 мар 2009, 00:07

GNU ARM. Здесь, по-моему, это не должно сильно влиять.
OYTIS
 
Сообщения: 76
Зарегистрирован: 22 апр 2008, 12:11

Re: Вопросы по программированию стенда SDK-2.0

Сообщение invaisor » 20 мар 2009, 00:28

OYTIS писал(а):GNU ARM. Здесь, по-моему, это не должно сильно влиять.

Интересует значение pclk, которое обычно указывается в стратовом коде (что-нибудь типа startup.s, где происходит начальная инициализация стенда).
Для значений управлющих регистров UART, которые вы привели
Код: Выделить всё
U0DLL   = 78;           
U0DLM   = 0x00;

pckl = 12 Mhz (pckl / (16 * 9600)), а если он 15 Mhz, то должно быть
Код: Выделить всё
U0DLL   = 98;           
U0DLM   = 0x00;

Кроме того можете посмотреть вот этот пример в котором кроме всего прочего осуществляется работа с UART по опросу (pclk = 15 Mhz).
Аватара пользователя
invaisor
 
Сообщения: 227
Зарегистрирован: 08 апр 2008, 16:08

Re: Вопросы по программированию стенда SDK-2.0

Сообщение OYTIS » 20 мар 2009, 21:59

PLLCFG установлено в 0x23 - достаточно подозрительное значение. В документации к LPC2292 написано, что этот регистр определяет некие коэффициенты, которые, в дополнение к частоте осциллятора, определяют тактовую частоту процессора. А как узнать/задать частоту осциллятора?
VPBDIV установлено в 0x00 (т.е. pclk = 0.25 cclk). Если PLLCFG = 0x23 все же задает частоту в 48 МГц (в чем есть некоторые сомнения), то pclk равно именно 12 МГц.
OYTIS
 
Сообщения: 76
Зарегистрирован: 22 апр 2008, 12:11

Re: Вопросы по программированию стенда SDK-2.0

Сообщение invaisor » 20 мар 2009, 23:12

OYTIS писал(а):PLLCFG установлено в 0x23 - достаточно подозрительное значение. В документации к LPC2292 написано, что этот регистр определяет некие коэффициенты, которые, в дополнение к частоте осциллятора, определяют тактовую частоту процессора. А как узнать/задать частоту осциллятора?
VPBDIV установлено в 0x00 (т.е. pclk = 0.25 cclk). Если PLLCFG = 0x23 все же задает частоту в 48 МГц (в чем есть некоторые сомнения), то pclk равно именно 12 МГц.

В SDK-2.0 Fosc = 12 MГц.
Тогда, если учитывать PLLCFG=0x23 (M = 4, P = 2), cclk = M * F_OSC = 4 * 12 (MHz) = 48 MHz.
VPBDIV=0x00 => pclk = cclk/4 = 12 MHz. То U0DLL = pclk / (16 * 9600) = 78 (для 9600).
Таким образом ваши настройки в принципе верны, значит дело в чем-то другом.
Проблема может еще быть в терминале (lpc2k_pgm), а именно там должно быть выставлено 9600 8 бит данные, 1 стоп бит, без контроля четности и аппаратного контроля. В Linux в качестве терминала можно также использовать minicom или вместо программирования с помощью lpc2k_pgm использовать lpc21isp, которая кроме того имеет встроенный терминал.
Попробуйте так же тестовую программу из аттача, она выводит данные по UART на 9600 и в ней все настройки как у вас. Если она не заработает, значит проблемы в терминале, что-то случилось со стендом или что-нибудь еще.
Вложения
uart_gnuarm_9600.rar
uart 9600
(6.05 Кб) Скачиваний: 454
Последний раз редактировалось invaisor 21 мар 2009, 18:11, всего редактировалось 1 раз.
Аватара пользователя
invaisor
 
Сообщения: 227
Зарегистрирован: 08 апр 2008, 16:08

Re: Вопросы по программированию стенда SDK-2.0

Сообщение OYTIS » 21 мар 2009, 16:29

Спасибо за помощь!
Кажется, внезапно он заработал. Просто сначала сделал Reset после программирования(хотя я и раньше это пробовал), а потом и так стал работать. Мистика... Правда, по каким-то причинам терминал желает выводить строки смещенными.
OYTIS
 
Сообщения: 76
Зарегистрирован: 22 апр 2008, 12:11

Re: Вопросы по программированию стенда SDK-2.0

Сообщение invaisor » 21 мар 2009, 18:10

OYTIS писал(а):Спасибо за помощь!
Кажется, внезапно он заработал. Просто сначала сделал Reset после программирования(хотя я и раньше это пробовал), а потом и так стал работать. Мистика... Правда, по каким-то причинам терминал желает выводить строки смещенными.

Вероятно ему не нравится сочетание "\r\n" можно попробовать просто "\n", т.е. без переноса каретки.
Удачи в дальнейшем освоение стенда SDK-2.0.
Аватара пользователя
invaisor
 
Сообщения: 227
Зарегистрирован: 08 апр 2008, 16:08

Re: Вопросы по программированию стенда SDK-2.0

Сообщение OYTIS » 26 мар 2009, 18:26

Да, спасибо, дело было именно в переносе каретки.
У меня новый ступор - на этот раз с LCD.
Код: Выделить всё
void main(void)
{
    init_pio();
    init_serial0();
    print("[MAIN] Start\r\n");
    lcd_init();
    print("[MAIN] Initialized\r\n");
    lcd_setpage(1);
    lcd_setcol(0, 5);
    lcd_writebyte(0, 0xF0);
    lcd_setcol(0, 20);
    lcd_writebyte(0, 0xF0);
    print("Byte read from main: %d\r\n", lcd_readbyte(0));
    print("Byte read from main: %d\r\n", lcd_readbyte(0));
    lcd_setcol(0, 25);
    print("Byte read from main: %d\r\n", lcd_readbyte(0));
    lcd_setpage(3);
    print("Byte read from main: %d\r\n", lcd_readbyte(0));
    while(1);
}

На экран ЖКИ не выводится ровным счетом ничего. Я добавил вывод на терминал в функции lcd_setcol и lcd_writebyte и на терминал выводится следующее:
Код: Выделить всё
[MAIN] Start
Byte read after setcol: 0
Byte read after setcol: 0
Byte read after write: 0
Byte read after write: 0
.............
[MAIN] Initialized
Byte read after setcol: 5
Byte read after write: 240
Byte read after setcol: 20
Byte read after write: 240
Byte read from main: 239  //читаем подряд три байта
Byte read from main: 0
Byte read from main: 255
Byte read after setcol: 25 //изменяем номер колонки и читаем подряд три байта
Byte read from main: 0
Byte read from main: 127
Byte read from main: 0
Byte read from main: 187  //изменяем номер колонки и читаем подряд три байта
Byte read from main: 0
Byte read from main: 255

Чтение из памяти после записи или установки колонки возвращает записанное значение, как и указано в документации.Но чтение из памяти ЖКИ возвращает что-то очень похожее на мусор. Пока единственное, что заставило экран ЖКИ как-то отреагировать - это установка статического управления - все пиксели становились черными и красиво светлели со временем =) Вот код некоторых функций (все команды LCD выполнены так же, как lcd_setcol, только адреса другие):
Код: Выделить всё
static void init_pio( void )
{
    BCFG2 = 0x0003501;
    BCFG3 = 0x0003501;
    PINSEL0 = 0x80550055;
    PINSEL1 = 0x154540A8;
    PINSEL2 = 0x0D6149D4;

    IO0DIR = 0x011A7D05;
    IO1DIR = 0x00000000;
    IO2DIR = 0x003F0000;
    IO3DIR = 0xC0000000;

    IO0CLR = 0xFFFFFFFF;
    IO1CLR = 0xFFFFFFFF;
    IO2CLR = 0xFFFFFFFF;
    IO3CLR = 0xFFFFFFFF;
}

void lcd_init()
{
    lcd_onoff(1);
    lcd_adc(0);
    lcd_stdrive(0);
    lcd_duty(1);
    lcd_setstring(0);
    lcd_clear(0);
}

void lcd_setpage(unsigned char page)
{
    unsigned char* address;

    if(page > 3)
        return;
    address = (unsigned char *)(IND1_BASE_ADDRESS | ADDR_CMD);
    while(lcd_status(0) & 0x90);
    *address = 0xB8|page;
    address = (unsigned char *)(IND2_BASE_ADDRESS | ADDR_CMD);
    while(lcd_status(1) & 0x90);
    *address = 0xB8|page;
}

void lcd_writebyte(unsigned char side, unsigned char byte)
{
    unsigned char* address;
    if( side > 1 )
        return;
    while(lcd_status(side) & 0x90);
    if ( side == 0 )
        address = (unsigned char *)(IND1_BASE_ADDRESS | ADDR_DATA);
    else
        address = (unsigned char *)(IND2_BASE_ADDRESS | ADDR_DATA);
    *address = byte;
    print("Byte read after write: %d\r\n", lcd_readbyte(side));
}

unsigned char lcd_readbyte(unsigned char side)
{
    unsigned char* address;
    if( side > 1 )
        return 0;
    while(lcd_status(side) & 0x90);
    if ( side == 0 )
        address = (unsigned char *)(IND1_BASE_ADDRESS | ADDR_DATA);
    else
        address = (unsigned char *)(IND2_BASE_ADDRESS | ADDR_DATA);
    return *address;
}

void lcd_clear(unsigned char color)
{
    unsigned char mask;
    unsigned char i, j;

    mask = (color)?0xFF:0x00;

    for( i = 0; i < 4; i++ )
    {
        lcd_setpage(i);
        lcd_setcol(0, 0);
        lcd_setcol(1, 0);
        for( j = 0; j < WIDTH/2; j++)
        {
            lcd_writebyte(0, mask);
            lcd_writebyte(1, mask);
        }
    }
}

void lcd_setcol(unsigned char side, unsigned char col)
{
    unsigned char* address;
    if( (side>1) || (col>WIDTH/2) )
        return;
    while(lcd_status(side) & 0x90);
    if ( side == 0 )
        address = (unsigned char *)(IND1_BASE_ADDRESS | ADDR_CMD);
    else
        address = (unsigned char *)(IND2_BASE_ADDRESS | ADDR_CMD);
    *address = col;

    print("Byte read after setcol: %d\r\n", lcd_readbyte(side));
}


Вопросы, собственно, все те же - на что следует обратить внимание. Возможно, тоже что-то в startup.s?
OYTIS
 
Сообщения: 76
Зарегистрирован: 22 апр 2008, 12:11

Re: Вопросы по программированию стенда SDK-2.0

Сообщение invaisor » 26 мар 2009, 20:45

OYTIS писал(а):У меня новый ступор - на этот раз с LCD. <..>
Вопросы, собственно, все те же - на что следует обратить внимание. Возможно, тоже что-то в startup.s?

Мне кажется, я догадываюсь в чем дело. Во всяком случае все остальное похоже на правду.
У контроллера ЖКИ есть такой порт IND_CL(P.012 на принц. схеме) - использование внешней тактовой частоты 2 кГц. Так вот, мы должны подавать на этот вход тактовый сигнал, иначе вся внутренняя логика контроллера работать не будет.
Самое простое, как это сделать - в прерывании от таймера(с переодичностью 4 kHz) дергать портом P.012:
Код: Выделить всё
#define VIC_TIMER0 0x4
#define VIC_TIMER0_bit (1 << VIC_TIMER0)
#define IND_CL    0x00001000L
static volatile unsigned char ind_clock = 0;

void timer0_handler(void) __attribute__ ((interrupt("IRQ")));

void timer0_handler(void) //собственно прерывание IRQ - timer 0
{
   /*lcd tick*/
     if ( ind_clock )
     {
        IO0SET |= IND_CL;
        ind_clock = 0;
     }
    else
    {
        IO0CLR |= IND_CL;
        ind_clock = 1;
     }

   T0IR = 0xff;                // Очистить прерывание таймера 0

   /* VIC acknowledge */
    VICVectAddr = 0;
}

void init_timer0( void )
{
   VICIntSelect &= ~VIC_TIMER0_bit; // IRQ от таймера 0
   VICVectAddr0  = (unsigned long)timer0_handler; /* Vector 0*/
   VICVectCntl0 = 0x20 | VIC_TIMER0; // Включить вектор прерываний для таймера 0
   VICIntEnable |=  VIC_TIMER0_bit; // Разрешить прерывания таймера 0

   T0TCR = 0;          // Выключить таймер 0
   T0PC = 0;           // Предделитель включен. Cclk = 60 МГц, pclk = 15 МГц
   T0PR = 10;          // Генерация 1,5 миллионов прерываний в секунд
   T0MR0 = 375;        // Инкрементировать до этого значения. Генерация 4000 Hz
   T0MCR = 3;          // Сброс и прерывание при совпадении с MR0 (match register 0)
   T0CCR = 0;          // Захват выключен
   T0EMR = 0;          // Внешних выводов сравнения нет
}
Аватара пользователя
invaisor
 
Сообщения: 227
Зарегистрирован: 08 апр 2008, 16:08

Пред.След.

Вернуться в SDK 2.0

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0

cron