Програмирование pic на СИ.

Поклонники продукции Microchip Technology Inc тусуются тут.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 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 байт, но это полный бред. Длина посылок (пакета) определяется объемом ОЗУ, который программист контроллера выделил на эти посылки. То есть, с учетом обсуждаемой задачи фактически нет никаких ограничений.
Ну и по существу ваших поисков.
Непонятно что вы хотите найти в интернете. То, что вы желаете получить, собственно к МК непосредственно отношения не имеет. Задача МК тут минимальна - просто проброс данных между шиной к ЭБУ и шиной к компьютеру. Ну и простейшие формирования пакетов или специальных сигналов шины. То есть это ПРЕЖДЕ ВСЕГО софт на компьютере. А МК лишь делается под этот софт как мост.
Реклама
Аватара пользователя
cxem
Грызет канифоль
Сообщения: 264
Зарегистрирован: Вт июн 30, 2009 09:17:54
Откуда: г.Сыктывкар

Re: Програмирование pic на СИ.

Сообщение cxem »

Не пойму, как тут он выталкивает биты на 21-ногу( KLINE_OUT LATBbits.LATB0)
Вложения
ediabaslib-binaries_2022_02_13.zip.rar
(18.74 КБ) 260 скачиваний
Реклама
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25261
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

Re: Програмирование pic на СИ.

Сообщение КРАМ »

[uquote="cxem",url="/forum/viewtopic.php?p=4181579#p4181579"]Не пойму, как[/uquote]
Имеется буфер 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;
            }
Аватара пользователя
cxem
Грызет канифоль
Сообщения: 264
Зарегистрирован: Вт июн 30, 2009 09:17:54
Откуда: г.Сыктывкар

Re: Програмирование pic на СИ.

Сообщение cxem »

Ни как не могу организовать выталкиваеия байта через 21-ногу.
Куда код надо вставить: в 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 на СИ.

Сообщение Аlex »

А на картинке что у вас ? Не выталкивание байте через ногу ? :)
Реклама
Аватара пользователя
cxem
Грызет канифоль
Сообщения: 264
Зарегистрирован: Вт июн 30, 2009 09:17:54
Откуда: г.Сыктывкар

Re: Програмирование pic на СИ.

Сообщение cxem »

по 22-ноге биты меняются красиво - 104 µs
А вот байт 0101 0101 по 21-ноге выходит не красиво
И функция while (1) должна его выталкивать постоянно
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Аlex »

cxem писал(а):И функция while (1) должна его выталкивать постоянно
Зачем ? У вас уже реализовано прерывание, пользуйтесь им.
Для чего вешать основной цикл ? :dont_know:
Аватара пользователя
R666
Встал на лапы
Сообщения: 108
Зарегистрирован: Пт фев 15, 2008 12:10:56
Откуда: Planet Of Earth: 50N,36E

Re: Програмирование pic на СИ.

Сообщение R666 »

Здравствуйте всем!
Столкнулся с непонятной проблемой при попытке подключить 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
}

В результате: при включении LCD выдает только самотест квадратиками. Осциллограф на RS и EN видит короткие положительные импульсы. На DATA - ничего не появляется. Похоже, что даже lcd_init() не исполняется :(

Пока не понятно, или это:
- кривые руки;
- некие отличия BOLYMIN BC2004 от стандарта (по даташиту вроде все сделал и развел правильно);
- другие более иные грабли?..

Посмотрите пожалуйста и ткните носом, ежели уж совсем где-то накосячил..
Аватара пользователя
Michael_Sch
Открыл глаза
Сообщения: 71
Зарегистрирован: Пт июл 12, 2013 13:53:52
Откуда: Санкт-Петербург

Re: Програмирование pic на СИ.

Сообщение Michael_Sch »

А это как: ((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 на СИ.

Сообщение R666 »

Спасибо, добегу до дому - буду разбираться с этой кучей скобок.
Вообще самому странным показалось, но именно так оно было в том примере обрисовано.
При этой форме на ножке EN импульс присутствует (можно предположить, что это как-то разработает)
Печаль в том, что на DATA стоят нули.. то есть не проходит содержимое команды :(
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Програмирование pic на СИ.

Сообщение OKF »

[uquote="Michael_Sch",url="/forum/viewtopic.php?p=4203730#p4203730"]А это как: ((LCD_EN = 1),(LCD_EN=0))?
Наверное надо:
LCD_EN=1;LCD_EN=0[/uquote]
Да пофигу.)
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Martian »

запятая пофигу?
а, там макрос... да, тогда пофигу.
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Програмирование pic на СИ.

Сообщение OKF »

Как раз макрос то желательно оформить:
#define LCD_STROBE() (LCD_EN = 1, LCD_EN = 0)
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Martian »

почему?
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Програмирование pic на СИ.

Сообщение OKF »

Что бы он был как один оператор. Типа:
if (true)
LCD_STROBE();
Аналогично оформляется через do {...} while (0). Почитайте.
Аватара пользователя
R666
Встал на лапы
Сообщения: 108
Зарегистрирован: Пт фев 15, 2008 12:10:56
Откуда: Planet Of Earth: 50N,36E

Re: Програмирование pic на СИ.

Сообщение R666 »

Переправил строб, как подсказали. Теперь он такой:

Код: Выделить всё

#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. :oops: Получается, при что "Reset" устанавливает туда "1".. в общем, нарисовал с осциллографа, наверно понятнее будет так..
Вложения
RS_osc.png
Примерно так выглядит RS.
(12.58 КБ) 121 скачивание
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Martian »

OKF, понял, спасибо! Да, удобно.
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Програмирование pic на СИ.

Сообщение OKF »

Считается что макросы вредны, они потенциальный источник ошибок... Да, в этом что то есть, но ошибки сплошь и рядом возникают и без них, и в других случаях, не стоит доводить это до параноидальных крайностей. А коль есть такой инструмент, почему его не использовать! Это всё ведь для удобства. С++ может и не быть, но препроцессор присутствует везде! И даже в те времена когда не было Си, макро ассемблер очень помогал. Просто чудеса с ним получались.)
Аватара пользователя
R666
Встал на лапы
Сообщения: 108
Зарегистрирован: Пт фев 15, 2008 12:10:56
Откуда: Planet Of Earth: 50N,36E

Re: Програмирование pic на СИ.

Сообщение R666 »

После поиска в даташите обнаружил, что на ножке EN должна появляться "1" после того, как установился RS и держаться там не меньше 140 ns (пока установятся DATA). Вывод на экран происходит чуть позже, по спаду EN. Похоже, что осциллограф все же видел что-то похожее на спад очень короткого импульса на EN. Получается, что надо задать длительность EN, но при попытке как-то вставить что-либо между LCD_EN = 1 и LCD_EN = 0 появляется тьма ошибок. В общем, чуда пока не получилось, похоже, что я что-то делаю не так..
Кстати, если написать так: (LCD_EN = 1; LCD_EN = 0) - то куча ошибок получается такая же. :(
OKF
Это не хвост, это антенна
Сообщения: 1393
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Програмирование pic на СИ.

Сообщение OKF »

Ну так нужно же понимать что ты делаешь, а не тыкаться как слепой котёнок.
Не лезьте в макро - рано ещё вам. Оформите функцией lcdStrobe() и напишите там то что вам надо.
Ответить

Вернуться в «PIC»