Програмирование pic на СИ.
- КРАМ
- Друг Кота
- Сообщения: 25259
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Програмирование pic на СИ.
[uquote="cxem",url="/forum/viewtopic.php?p=4173259#p4173259"]Обидно за PIC18F25K80, который проигрывает 2 транзисторам
1.Скорость связи с ЭБУ слабая: Если даже UART поднять до 115200 бод
2.Почему-то говорят, что он не умеет отправлять в ЭБУ байты длиннее 8 байт[/uquote]
Вы пишите чушь.
Скорость связи с ЭБУ определяется самим ЭБУ. Если вы утверждаете, что рейт у ЭБУ 10400, то как можно работать на 115200? Причем тут МК, рейт аппаратного УАРТа которого определяется только осциллятором и сеткой деления его частоты на 4?
Я не знаю кто вам сказал об ограничении в 8 байт, но это полный бред. Длина посылок (пакета) определяется объемом ОЗУ, который программист контроллера выделил на эти посылки. То есть, с учетом обсуждаемой задачи фактически нет никаких ограничений.
Ну и по существу ваших поисков.
Непонятно что вы хотите найти в интернете. То, что вы желаете получить, собственно к МК непосредственно отношения не имеет. Задача МК тут минимальна - просто проброс данных между шиной к ЭБУ и шиной к компьютеру. Ну и простейшие формирования пакетов или специальных сигналов шины. То есть это ПРЕЖДЕ ВСЕГО софт на компьютере. А МК лишь делается под этот софт как мост.
1.Скорость связи с ЭБУ слабая: Если даже UART поднять до 115200 бод
2.Почему-то говорят, что он не умеет отправлять в ЭБУ байты длиннее 8 байт[/uquote]
Вы пишите чушь.
Скорость связи с ЭБУ определяется самим ЭБУ. Если вы утверждаете, что рейт у ЭБУ 10400, то как можно работать на 115200? Причем тут МК, рейт аппаратного УАРТа которого определяется только осциллятором и сеткой деления его частоты на 4?
Я не знаю кто вам сказал об ограничении в 8 байт, но это полный бред. Длина посылок (пакета) определяется объемом ОЗУ, который программист контроллера выделил на эти посылки. То есть, с учетом обсуждаемой задачи фактически нет никаких ограничений.
Ну и по существу ваших поисков.
Непонятно что вы хотите найти в интернете. То, что вы желаете получить, собственно к МК непосредственно отношения не имеет. Задача МК тут минимальна - просто проброс данных между шиной к ЭБУ и шиной к компьютеру. Ну и простейшие формирования пакетов или специальных сигналов шины. То есть это ПРЕЖДЕ ВСЕГО софт на компьютере. А МК лишь делается под этот софт как мост.
- Реклама
Re: Програмирование pic на СИ.
Не пойму, как тут он выталкивает биты на 21-ногу( KLINE_OUT LATBbits.LATB0)
- Вложения
-
- ediabaslib-binaries_2022_02_13.zip.rar
- (18.74 КБ) 260 скачиваний
- КРАМ
- Друг Кота
- Сообщения: 25259
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Програмирование pic на СИ.
[uquote="cxem",url="/forum/viewtopic.php?p=4181579#p4181579"]Не пойму, как[/uquote]
Имеется буфер out_data. Этот буфер маскируется 0x01 и результат выталкивается в KLINE_OUT (это дефайн ноги). Затем буфер сдвигается вправо на 1 бит и снова маскируется. И так побитно выводится в ногу с интервалом определяемым TMR2.
Код совершенно элементарный:
Имеется буфер out_data. Этот буфер маскируется 0x01 и результат выталкивается в KLINE_OUT (это дефайн ноги). Затем буфер сдвигается вправо на 1 бит и снова маскируется. И так побитно выводится в ногу с интервалом определяемым TMR2.
Код совершенно элементарный:
Код: Выделить всё
KLINE_OUT = 1; // start bit
uint8_t out_data = *ptr++;
for (uint8_t j = 0; j < 8; j++)
{
while (!PIR1bits.TMR2IF) {}
PIR1bits.TMR2IF = 0;
if ((out_data & 0x01) != 0)
{
KLINE_OUT = 0;
}
else
{
KLINE_OUT = 1;
}
out_data >>= 1;
}
Re: Програмирование pic на СИ.
Ни как не могу организовать выталкиваеия байта через 21-ногу.
Куда код надо вставить: в void main() или void interrupt ?
Куда код надо вставить: в void main() или void interrupt ?
Спойлер
Код: Выделить всё
#include <xc.h>
#include <stdint.h>
#define KLINE_OUT LATBbits.LATB0
void init(void)
{
// настройка генератора
// в регистре конфигурации выбран внешний тактовый генератор XT, умножитель выключен
// в OSCCON выбираем 4 мГц основной генератор
OSCTUNE = 0b00000000;
// ||++++++---TUN<5:0>: 000000 = Центральная частота; Быстрый Осциллятор RC работает на калиброванной частоте
// |+---------PLLEN: Frequency Multiplier 4xPLL 0 = PLL выключен
// +----------: Internal Oscillator Low-Frequency
OSCCON = 0b01010000; // 101 = HF-INTOSC/4 output frequency is used (4 MHz)
// ||||||++---SCS<1:0>: тактовая частота берется с основного модуля. основной генератор (работа через PLL должен быть 00)
// |||||+-----HFIOFS: бит - Частота стабильна
// ||||+------OSTS: бит статуса (какой выбран генератор)
// |+++-------IRCF<2:0>: выбор частоты тактового генератора
// +----------: функция генератора в режиме сна. SPLLEN умножитель 1-включен
OSCCON2 = 0b00000000;
// |||||||+---LFIOFS:бит стабильной частоты LFINTOSC режима
// ||||||+----MFIOFS:бит стабильной частоты MFINTOSC режима
// |||||+-----PRISD:бит отключения главного (внешнего) генератора
// ||||+------SOSCGO: бит контроля запуска вторичного (внешнего) генератора
// |||+-------MFIOSEL: бит переключения источника чатоты для MFINTOSC режима
// ||+--------Unimplemented: Read as ‘0’.
// |+---------SOSCRUN: бит статуса источника частоты от вторичного генератора
// +----------: бит статуса получения частоты от умножителя тактовой чатоты
//---------------------------------------
// настройка портов
ADCON1=1; // Отключаем все аналоговые буфера
ADCON1=0b01111111; // Отключаем все аналоговые буфера
TRISBbits.TRISB0 = 0; // 21-нога out
LATBbits.LATB0 = 1; // установить на B0 плюс
TRISBbits.TRISB1 = 0; // 22-нога out
LATBbits.LATB1 = 1; // установить на B1 плюс
// UART
TRISCbits.TRISC6 = 0; // TX output
TRISCbits.TRISC7 = 1; // RX input
// настройка Open1USART
Open1USART ( USART_TX_INT_OFF & // Прерывание передачи OFF
USART_RX_INT_ON & // Получать прерывание ON
USART_ASYNCH_MODE & // Асинхронный режим
USART_EIGHT_BIT & // 8-bit Передача / прием
USART_CONT_RX & // Непрерывный прием
USART_BRGH_HIGH, // Высокая скорость передачи бода
SPBRG = 25 ); // ((4000000 : 16) : 9600) - 1 = 25,04 Погрешность скорости обмена 9600
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define Bit_out_21 LATBbits.LATB0 // Bit_out = 21-нога
#define Bit_out_22 LATBbits.LATB1 // Bit_out = 22-нога
uint8_t out_data = 0x55;
void main()
{
init();
int j ; // переменная j
/////////////////////////Регистр T2CON////////////////////
T2OUTPS0 = 0; // Выбор коэффициента выходного делителя TMR2 0000 = 1:1
T2OUTPS1 = 0;
T2OUTPS2 = 0;
T2OUTPS3 = 0;
TMR2ON = 1; // Включение модуля TMR2
T2CKPS0 = 0; // Выбор коэффициента деления предделителя TMR2 00 = 1:1
T2CKPS1 = 0;
/////////////////////////Регистр INTCON//////////////////////////
GIE = 1; // Глобальное разрешение прерываний 1 = разрешены все немаскированные прерывания
PEIE = 1; // ГРазрешение прерываний от периферийных модулей 1 = разрешены все немаскированные прерывания периферийных модулей
//////////////////////////Регистр PIR1/////////////////////////////////////
TMR2IF = 1; // Флаг прерывания по переполнению TMR2
//////////////////////////Регистр PIE1////////////////////////////////////
TMR2IE = 1; // Разрешение прерывания по переполнению TMR2
PR2 = 104;
while (1)
{
for (uint8_t j = 0; j < 8; j++) // счётчик до 8 бит
while (TMR2IF== 1) {} // Флаг таймера
PIR1bits.TMR2IF = 0; // сброс Флага
if ((out_data & 0x01) != 0) // буфер out_data(0х55) 0101 0101 маскируем все биты, кроме этого 0101 0101
{
Bit_out_21 = 0;
}
else
{
Bit_out_21 = 1;
}
out_data >>= 1;
}
}
//////////////////////// Программа прерывания обслуживания - ISR////////////////////////
void interrupt ISR ()
{
Bit_out_22 = ~Bit_out_22; // Переключите 104микросекунд
TMR2IF = 0; // сбросить флаг
}- Вложения
-
- 104 µs.png
- (62.62 КБ) 169 скачиваний
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Програмирование pic на СИ.
А на картинке что у вас ? Не выталкивание байте через ногу ? 
- Реклама
Re: Програмирование pic на СИ.
по 22-ноге биты меняются красиво - 104 µs
А вот байт 0101 0101 по 21-ноге выходит не красиво
И функция while (1) должна его выталкивать постоянно
А вот байт 0101 0101 по 21-ноге выходит не красиво
И функция while (1) должна его выталкивать постоянно
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Програмирование pic на СИ.
Зачем ? У вас уже реализовано прерывание, пользуйтесь им.cxem писал(а):И функция while (1) должна его выталкивать постоянно
Для чего вешать основной цикл ?
- R666
- Встал на лапы
- Сообщения: 108
- Зарегистрирован: Пт фев 15, 2008 12:10:56
- Откуда: Planet Of Earth: 50N,36E
Re: Програмирование pic на СИ.
Здравствуйте всем!
Столкнулся с непонятной проблемой при попытке подключить LCD BOLYMIN BC2004 к PIC 16F877A. (Использую MPLAB 8.92.00 в связке с HItech v9.50 std PL3 на WinXP.) В примерах компилятора есть образец такого подключения, но там используются порты A и D. Хотел выделить для управления LCD только порт D, переправил lcd.c, но похоже что-то пошло не так.. Кроме этого RD0 и RD1 были уже заняты. Так как с LCD ничего обратно не выводится, то RW был наглухо включен в "0" и не использован программно.
В результате: при включении LCD выдает только самотест квадратиками. Осциллограф на RS и EN видит короткие положительные импульсы. На DATA - ничего не появляется. Похоже, что даже lcd_init() не исполняется
Пока не понятно, или это:
- кривые руки;
- некие отличия BOLYMIN BC2004 от стандарта (по даташиту вроде все сделал и развел правильно);
- другие более иные грабли?..
Посмотрите пожалуйста и ткните носом, ежели уж совсем где-то накосячил..
Столкнулся с непонятной проблемой при попытке подключить LCD BOLYMIN BC2004 к PIC 16F877A. (Использую MPLAB 8.92.00 в связке с HItech v9.50 std PL3 на WinXP.) В примерах компилятора есть образец такого подключения, но там используются порты A и D. Хотел выделить для управления LCD только порт D, переправил lcd.c, но похоже что-то пошло не так.. Кроме этого RD0 и RD1 были уже заняты. Так как с LCD ничего обратно не выводится, то RW был наглухо включен в "0" и не использован программно.
Код: Выделить всё
В самом начале было сделано так:
void wakeup ()
{
TRISA = 0b00111111; //PortA input RA0...RA5
TRISB = 0b00000000; //TRISB = 0 portB output
TRISC = 0b11111110; //TRISC turn RC0 output
TRISD = 0b00000011; //TRISD make D2..D7 outputs,D2=sck,D1=inpLost
TRISE = 0b00000111; //TRISE = 1 portE inputs, PSP=0 RD in GP mode
ADCON0 = 0b00000000; // RA0..RA5 are digital inputs
ADCON1 = 0b00000111; // RA0..RA5 are not analog
PORTA = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
PORTE = 0;
RBPU = 0; // RB pull-up on
lcd_init();
lcd_clear();
};
Текст lcd.c (в комментариях то, что было до изменений):
/*
* LCD interface example
* Uses routines from delay.c
* This code will interface to a standard LCD controller
* like the Hitachi HD44780. It uses it in 4 bit mode, with
* the hardware connected as follows (the standard 14 pin
* LCD connector is used):
*
* PORTD bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
* PORTA bit 3 is connected to the LCD RS input (register select)
* PORTA bit 1 is connected to the LCD EN bit (enable)
*
* (это мною уже добавлено)
* LCD is BOLYMIN BC2004.
* To use these routines, set up the port I/O (TRISD!) then
* as it described earlier!
* This project don't use PORTA for LCD management.
*
*/
#include <pic.h>
#include "lcd.h"
#include "delay.h"
#define LCD_RS RD2 //rem was LCD_RS RA3
//#define LCD_RW RA2 //rem RW allways 0
#define LCD_EN RD3 //rem LCD_EN RA1
#define LCD_DATA PORTD
#define LCD_STROBE() ((LCD_EN = 1),(LCD_EN=0))
/* write a byte to the LCD in 4 bit mode */
void
lcd_write(unsigned char c)
{
DelayUs(40);
LCD_DATA = ( ( c >> 4 ) & 0x0F );
LCD_STROBE();
LCD_DATA = ( c & 0x0F );
LCD_STROBE();
}
/* Clear and home the LCD */
void
lcd_clear(void)
{
LCD_RS = 0;
lcd_write(0x1);
DelayMs(2);
}
/* write a string of chars to the LCD */
void
lcd_puts(const char * s)
{
LCD_RS = 1; // write characters
while(*s)
lcd_write(*s++);
}
/* write one character to the LCD */
void
lcd_putch(char c)
{
LCD_RS = 1; // write characters
lcd_write( c );
}
/* Go to the specified position */
void
lcd_goto(unsigned char pos)
{
LCD_RS = 0;
lcd_write(0x80+pos);
}
/* initialise the LCD - put into 4 bit mode */
void
lcd_init()
{
char init_value;
//ADCON1 = 0x06; //Disable analog pins on PORTA. (ADCON1 now not used!)
init_value = 0x3;
//TRISA=0; //rem in original was this
TRISD=0b00000011; //Checked, RD0,RD1 are inputs - don't touch them!
LCD_RS = 0;
LCD_EN = 0;
//LCD_RW = 0; //rem RW allways 0
DelayMs(15); // wait 15mSec after power applied,
LCD_DATA = init_value;
LCD_STROBE();
DelayMs(5);
LCD_STROBE();
DelayUs(200);
LCD_STROBE();
DelayUs(200);
LCD_DATA = 2; // Four bit mode
LCD_STROBE();
lcd_write(0x28); // Set interface length
lcd_write(0xF); // Display On, Cursor On, Cursor Blink
lcd_clear(); // Clear screen
lcd_write(0x6); // Set entry Mode
}
Пока не понятно, или это:
- кривые руки;
- некие отличия BOLYMIN BC2004 от стандарта (по даташиту вроде все сделал и развел правильно);
- другие более иные грабли?..
Посмотрите пожалуйста и ткните носом, ежели уж совсем где-то накосячил..
- Michael_Sch
- Открыл глаза
- Сообщения: 71
- Зарегистрирован: Пт июл 12, 2013 13:53:52
- Откуда: Санкт-Петербург
Re: Програмирование pic на СИ.
А это как: ((LCD_EN = 1),(LCD_EN=0))?
Наверное надо:
LCD_EN=1;LCD_EN=0
Наверное надо:
LCD_EN=1;LCD_EN=0
Зачем, зубодер распроклятый, мучительный тянешь момент?
Тебе, стоматолог, сто матов измученный шлет пациент! (с) Вадим Шефнер
Тебе, стоматолог, сто матов измученный шлет пациент! (с) Вадим Шефнер
- R666
- Встал на лапы
- Сообщения: 108
- Зарегистрирован: Пт фев 15, 2008 12:10:56
- Откуда: Planet Of Earth: 50N,36E
Re: Програмирование pic на СИ.
Спасибо, добегу до дому - буду разбираться с этой кучей скобок.
Вообще самому странным показалось, но именно так оно было в том примере обрисовано.
При этой форме на ножке EN импульс присутствует (можно предположить, что это как-то разработает)
Печаль в том, что на DATA стоят нули.. то есть не проходит содержимое команды
Вообще самому странным показалось, но именно так оно было в том примере обрисовано.
При этой форме на ножке EN импульс присутствует (можно предположить, что это как-то разработает)
Печаль в том, что на DATA стоят нули.. то есть не проходит содержимое команды
Re: Програмирование pic на СИ.
[uquote="Michael_Sch",url="/forum/viewtopic.php?p=4203730#p4203730"]А это как: ((LCD_EN = 1),(LCD_EN=0))?
Наверное надо:
LCD_EN=1;LCD_EN=0[/uquote]
Да пофигу.)
Наверное надо:
LCD_EN=1;LCD_EN=0[/uquote]
Да пофигу.)
Re: Програмирование pic на СИ.
запятая пофигу?
а, там макрос... да, тогда пофигу.
а, там макрос... да, тогда пофигу.
Re: Програмирование pic на СИ.
Как раз макрос то желательно оформить:
#define LCD_STROBE() (LCD_EN = 1, LCD_EN = 0)
#define LCD_STROBE() (LCD_EN = 1, LCD_EN = 0)
Re: Програмирование pic на СИ.
почему?
Re: Програмирование pic на СИ.
Что бы он был как один оператор. Типа:
if (true)
LCD_STROBE();
Аналогично оформляется через do {...} while (0). Почитайте.
if (true)
LCD_STROBE();
Аналогично оформляется через do {...} while (0). Почитайте.
- R666
- Встал на лапы
- Сообщения: 108
- Зарегистрирован: Пт фев 15, 2008 12:10:56
- Откуда: Planet Of Earth: 50N,36E
Re: Програмирование pic на СИ.
Переправил строб, как подсказали. Теперь он такой:
В результате:
- при старте на LCD_RS проходят два положительных импульса;
- LCD_EN из состояния , похожего на Z, переходит в "0";
- на шине LCD_DATA - при нажатии "Reset" -"1", и дальше "0", без намека на движение;
- на экране результат самотеста LCD (черно-белые через одну строчки)..
.. в общем ничего не изменилось, похоже, что тут глобальная панама какая-то..
upd: если R/W у нас постоянно "0", то (ЕЯПП) должно сначала поставить RS=0, после этого EN=1, далее установить данные на D4..D7, и тогда по заднему фронту EN все выведется на экран.
Может быть, что-то неправильно с длительностями RS и EN? А вот как их можно изменить?
upd2: прошу прощения, неправильно описал RS.
Получается, при что "Reset" устанавливает туда "1".. в общем, нарисовал с осциллографа, наверно понятнее будет так..
Код: Выделить всё
#define LCD_STROBE() (LCD_EN = 1, LCD_EN = 0)- при старте на LCD_RS проходят два положительных импульса;
- LCD_EN из состояния , похожего на Z, переходит в "0";
- на шине LCD_DATA - при нажатии "Reset" -"1", и дальше "0", без намека на движение;
- на экране результат самотеста LCD (черно-белые через одну строчки)..
.. в общем ничего не изменилось, похоже, что тут глобальная панама какая-то..
upd: если R/W у нас постоянно "0", то (ЕЯПП) должно сначала поставить RS=0, после этого EN=1, далее установить данные на D4..D7, и тогда по заднему фронту EN все выведется на экран.
Может быть, что-то неправильно с длительностями RS и EN? А вот как их можно изменить?
upd2: прошу прощения, неправильно описал RS.
- Вложения
-
- RS_osc.png
- Примерно так выглядит RS.
- (12.58 КБ) 121 скачивание
Re: Програмирование pic на СИ.
OKF, понял, спасибо! Да, удобно.
Re: Програмирование pic на СИ.
Считается что макросы вредны, они потенциальный источник ошибок... Да, в этом что то есть, но ошибки сплошь и рядом возникают и без них, и в других случаях, не стоит доводить это до параноидальных крайностей. А коль есть такой инструмент, почему его не использовать! Это всё ведь для удобства. С++ может и не быть, но препроцессор присутствует везде! И даже в те времена когда не было Си, макро ассемблер очень помогал. Просто чудеса с ним получались.)
- R666
- Встал на лапы
- Сообщения: 108
- Зарегистрирован: Пт фев 15, 2008 12:10:56
- Откуда: Planet Of Earth: 50N,36E
Re: Програмирование pic на СИ.
После поиска в даташите обнаружил, что на ножке EN должна появляться "1" после того, как установился RS и держаться там не меньше 140 ns (пока установятся DATA). Вывод на экран происходит чуть позже, по спаду EN. Похоже, что осциллограф все же видел что-то похожее на спад очень короткого импульса на EN. Получается, что надо задать длительность EN, но при попытке как-то вставить что-либо между LCD_EN = 1 и LCD_EN = 0 появляется тьма ошибок. В общем, чуда пока не получилось, похоже, что я что-то делаю не так..
Кстати, если написать так: (LCD_EN = 1; LCD_EN = 0) - то куча ошибок получается такая же.
Кстати, если написать так: (LCD_EN = 1; LCD_EN = 0) - то куча ошибок получается такая же.
Re: Програмирование pic на СИ.
Ну так нужно же понимать что ты делаешь, а не тыкаться как слепой котёнок.
Не лезьте в макро - рано ещё вам. Оформите функцией lcdStrobe() и напишите там то что вам надо.
Не лезьте в макро - рано ещё вам. Оформите функцией lcdStrobe() и напишите там то что вам надо.


