Страница 48 из 103
Re: Програмирование pic на СИ.
Добавлено: Сб дек 16, 2017 19:39:00
SpeedFighter
Да, с этим уже разобрался, спасибо!
А как перевести из float в int / unsigned int?
2.5*(5.0*ADRESH/(256.0)) - 1.0; - Вот это хотел бы перевести в int.
Re: Програмирование pic на СИ.
Добавлено: Сб дек 16, 2017 21:34:24
КРАМ
Вы занимаетесь отчаянной ерундой.
Никакого флоата не требуется.
Вы пытаетесь считать на МК как на калькуляторе. Это совершенно пустое мероприятие.
Для чего Вам нужны вольты?
Re: Програмирование pic на СИ.
Добавлено: Сб дек 16, 2017 22:07:46
SpeedFighter
Поясняю, для чего:
Я через вольты написал приблизительную функцию для нажатой клавиши:
0,4 В - 0
0,8 В - 1
и так далее.
Но увы, придется нажатие клавиш разных чисто через ADRESH обрабатывать, что некрасиво, увы.
P.S. Есть гайд небольшой, по работе с LCD? (lm016l - если конкретно).
Re: Програмирование pic на СИ.
Добавлено: Сб дек 16, 2017 22:37:13
КРАМ
Это апокалиптический бред.
Вместо внятного дефайна константы сравнения Вы считаете никому не нужный флоат.
Уважаемый, Вам бы основы программирования почитать, прежде чем писать код...
ЗЫ. Вывод на дисплей тоже не требует флоата. На дисплей выводят ДВОИЧНО-ДЕСЯТИЧНОЕ ЦЕЛОЕ ЧИСЛО, а не флоат. Точку зажигают в необходимой позиции независимо от расчета цифр в разрядах.
Re: Програмирование pic на СИ.
Добавлено: Вс дек 17, 2017 07:19:38
SpeedFighter
Понял, ладно.
Но библиотеку для работы с LCD все равно не могу найти для PIC.
Re: Програмирование pic на СИ.
Добавлено: Вс дек 17, 2017 09:22:23
КРАМ
А к чему она?
Есть даташит на ЖК, вот и напишите драйвер сами.
Re: Програмирование pic на СИ.
Добавлено: Вс дек 17, 2017 10:15:15
SpeedFighter
Мне так удобнее было бы разобраться.
Так-то вот, нашел один код, который я в проект свой вставил:
Спойлер
Код: Выделить всё
/*
* File: newmain.c
* Автор: ViktoR
* Программа: Передача параметров с клавиатуры
* Создана: 15 декабря 2017 г., 15:44
*/
// Подключаем библиотеки
#include <stdio.h> // Стандартная библиотека Си для ввода-вывода
#include <stdlib.h> // Стандартная библиотека Си для контроля
#include <xc.h> // Библиотека компилятора XC8 для работы с PIC
// Определение параметров микроконтроллера
#define _XTAL_FREQ 16000000 // Тактовая частота 16 МГц (см. OSCCON)
#define DELAY_ADC 10 // Задержка АЦП, в мс
// Определение параметров для подключение периферии
// Светодиоды
#define LED_ERROR RB6 // Светодиод, индицирующие статус набора (ошибка)
#define LED_OK RB7 // Светодиод, индицирующие статус набора (норм)
#define KEYBOARD AN0 // Определяем порт для подключения клавиатуры через АЦП
// ВАЖНО: ПОРТ ДОЛЖЕН ПОДДЕРЖИВАТЬ АНАЛОГОВЫЕ СИГНАЛЫ (НАЗЫВАТЬСЯ AN)
// LCD биты и переменные
#define LCD_width 15 // Ширина дисплея
#define LCD_height 1 // Высота дисплея
#define RS_1 RB6 = 1 // RC0
#define RS_0 RB6 = 0 // RC0
#define E_1 RB5 = 1 // RA0
#define E_0 RB5 = 0 // RA0
// LCD биты и переменные:
const unsigned char addLUT[4] = {0x80, 0xC0, 0x94, 0xD4};
unsigned char LCD_Address, LCD_Line;
char buffer[15];
void delay(unsigned int p)
{
unsigned int i;
for(i=0;i<p ;i++){asm("NOP");}
}
// LCD
void WriteNibble(unsigned char data)
{
E_1;
PORTC = (data & 0x0F)*16;
E_0;
delay(300);
}
void WriteByte(unsigned char data)
{
E_1;
PORTC = (data >> 4)*16;
E_0;
E_1;
PORTC = (data & 0xF)*16;
E_0;
delay(300);
}
void SetLCDPosition(char row, char col)
{
RS_0;
WriteByte(addLUT[row] + col);
RS_1;
LCD_Address=col;
LCD_Line = row;
}
void ClearLCD(void)
{
RS_0;
WriteByte(0x01);
delay(1000);
RS_1;
SetLCDPosition(0,0);
}
void ShowChar(unsigned char c)
{
RS_1;
WriteByte(c);
LCD_Address++;
if(LCD_Address>LCD_width)
if(LCD_Line<LCD_height)
SetLCDPosition(LCD_Line+1,0);
else
SetLCDPosition(0,0);
}
void ShowStr(unsigned char *s)
{
while (*s != 0) ShowChar(*s++);
}
void InitLCD(void)
{
int i;
E_0;
RS_0;
delay(5000);
WriteNibble(0x33);
WriteNibble(0x33);
WriteNibble(0x33);
WriteNibble(0x22);
WriteByte(0x28);
WriteByte(0x01);
WriteByte(0x10);
WriteByte(0x06);
WriteByte(0x0C);
for(i=0x40; i < 0x5F; i++)
{
delay(1000);
RS_0;
WriteByte(i);
delay(1000);
ShowChar(0);
}
RS_1;
SetLCDPosition(0, 0);
buffer[0] = 'O';
buffer[1] = 'k';
buffer[2] = '\0';
ShowStr(buffer);
}
// -LCD биты
/*// Объявляем глобальные переменные:
int gNumber[5] = {0}; // Массив с разрядами набранного числа*/
// Объявляем используемые функции
void Prepare(); // Функция подготовки МК (настройка портов и т.п.)
int get_Number(); // Функция получения набранного номера
void DelLastNumb(int i); // Функция удаления последней цифры
void StartADC(); // Функция запуска АЦП
int main() // Главная функция
{
// Определяем локальные переменные:
/*int key, i = 0; // Переменные для определения нажатой кнопки и разрядности соотвественно
float Middle; // Костыльная переменная*/
// Вызываем нужные функции:
Prepare(); // Вызов функции подготовки
delay(100);
InitLCD(); // инициализация дисплея
delay(10000);
ClearLCD(); // очистка дисплея
ShowStr("Test1"); // вывод строки*/
/*while(1) // Бесконечный цикл работы МК
{
PORTC = ADRESH;
// Проверка на окончание преобразование АЦП и фильтрация шумов)
if((ADCON0bits.GO == 0))
{
if(ADRESH > 15)
{
LED_OK = 1;
LED_ERROR = 0;
StartADC();
}
else
{
LED_OK = 0;
LED_ERROR = 1;
StartADC();
}
}
}*/
return 0;
}
// Описание функции подготовки (настройки) параметров МК
void Prepare()
{
// Настройки МК:
OSCCON = (1<<4)|(1<<5)|(1<<6); // Установка IRCF = '111' для частоты в 16 MHz
ADCON1bits.VCFG0 = 0; // Установка опорного напряжения
ADCON1bits.VCFG1 = 0; // Установка опорного напряжения
TRISA = 0b1111111; // Ножки RA0 - R7 - вход
TRISB = 0b0000000; // Ножки RB0-RB7 - выход
TRISC = 0b0000000; // Ножки RC0-RC7 - выход
ANCON0 = 1; // AN как аналоговый входы
// Настройки АЦП:
ADCON2bits.ACQT = 1; // 2 = 4TAD
ADCON2bits.ADCS = 0b010; // 16 TOSC
ADCON0bits.CHS4 = 0; // Настройка входа АЦП (AN0)
ADCON0bits.CHS3 = 0; // Настройка входа АЦП (AN0)
ADCON0bits.CHS2 = 0; // Настройка входа АЦП (AN0)
ADCON0bits.CHS1 = 0; // Настройка входа АЦП (AN0)
ADCON0bits.CHS0 = 0; // Настройка входа АЦП (AN0)
ADCON2bits.ADFM = 0; // Левое выравынивание
ADCON0bits.ADON = 1; // Включили модуль АЦП
PIR1bits.ADIF = 0; // Сброс прерываний АЦП
PIE1bits.ADIE = 0; // Разрешили прерывание АЦП
INTCONbits.PEIE = 0; // Периферийные прерывания разрешены
INTCONbits.GIE = 0; // Глобальные прерывания разрешены
ADCON0bits.GO = 1 ; // Метка начала преобразования
}
/*// Описание фунцкии удаления последнего номера:
void DelLastNumb(int i)
{
if(i == 0)
{
gNumber[0] = 0;
}
for(int j = 0; j <= i; j++)
{
if (j == i)
{
gNumber[j] = 0;
}
else
{
gNumber[j] = gNumber[j+1];
}
}
}*/
// Описание функции получения числа
/*int get_Number()
{
return (gNumber[4]*10000 + gNumber[3]*1000 + gNumber[2]*100 + gNumber[1]*10 + gNumber[0]);
}*/
// Описание функции запуска АЦП
void StartADC()
{
__delay_ms(DELAY_ADC); // Задержка перед началом АЦП
ADCON0bits.GO = 1 ; // Метка начала преобразования
}
Жаль только, что что слишком часто сменяются надписи
Ok и
Test, но это задержки тут кривые, наверное.
Re: Програмирование pic на СИ.
Добавлено: Пн фев 19, 2018 17:55:16
xterro
Что скажете по поводу компилятора sdcc? Он вроде как умеет pic16/18 и бесплатный?
Re: Програмирование pic на СИ.
Добавлено: Вт мар 13, 2018 18:45:25
uldemir
ниид хелп. Компилятор XC8 не хочет проглатывать такую простую конструкцию
Мне нужно его просто прочитать, но данные сохранять не нужно. Почему-то казалось, что это вполне легальная конструкция.
Спойлер
контекст:Код: Выделить всё
if (RCIE && RC1IF) {
RC1IF = 0;
if (FERR == 1) {
FERR = 0; // framing error clear, but skip data
=RC1REG;
} else {
if (uart_count < UART_BUFFER_SIZE) {
*wr_ptr = RC1REG;
uart_count++;
if (++wr_ptr > &uart_buf[UART_BUFFER_SIZE]) wr_ptr = uart_buf;
}
}
}
Re: Програмирование pic на СИ.
Добавлено: Вт мар 13, 2018 18:51:06
driver_gv
Может надо RCREG1 ? и что пишет то при компиляции?
Re: Програмирование pic на СИ.
Добавлено: Вт мар 13, 2018 18:55:01
Аlex
Перед знаком "=" всегда должен стоят "адресат".
Просто прочитать можно написав имя регистра без всяких лишних знаков.
Добавлено after 3 minutes 25 seconds:
А вообще, в Вашем коде можно сделать чтение регистра во временную переменную, вначале условия, а потом уже работать с ней. Т.к. :
1. Он в коде у Вас 2 раза читается.
2. Компилятор, в любом случае, выделит место для его чтения.
Re: Програмирование pic на СИ.
Добавлено: Вт мар 13, 2018 19:16:33
uldemir
Не читается - второе под условием else - будет или один или второй. Думал, может кто замечание по реализации кольцевого буффера скажет... чёрт, вижу еще один затык: если буфер переполнен, то я тоже не читаю регистр, а флаг прерывания снимаю - тоже может повиснуть и не отвиснуть.
Re: Програмирование pic на СИ.
Добавлено: Вт мар 13, 2018 19:28:33
Аlex
Вы, по всей видимости, меня не поняли.
Код: Выделить всё
if (RCIE && RC1IF) {
unsigned char rcreg=RC1REG;
..............
..............
И дальше читаем переменную
rcreg где нужно. А
RC1REG будет прочитан всегда, когда вызовется прерывание.
Добавлено after 4 minutes 17 seconds:
Кстати,
RC1IF = 0; - бесполезное действие. Он сбрасывается аппаратно, при чтении регистра
RCREG.
Re: Програмирование pic на СИ.
Добавлено: Вт мар 13, 2018 21:25:01
uldemir
спасибо за подсказку по поводу флага прерывания. а по поводу ошибки фрейма - так делать нельзя. флаг надо проверить до считывания регистра. и сбрасывать его как я пытался - тоже нельзя - он только читается.
Re: Програмирование pic на СИ.
Добавлено: Вт мар 13, 2018 21:27:02
Аlex
Тогда сделайте так, да и всё :
Код: Выделить всё
if(FERR) {
unsigned char rcreg=RC1REG;
} else {
А остальное оставьте как есть.
PS: Проц какой ?
Re: Програмирование pic на СИ.
Добавлено: Ср мар 14, 2018 17:20:55
uldemir
pic18f25k40. Cделал так:
Код: Выделить всё
if (RCIE && RC1IF) {
if (FERR == 1) { // framing error clear, but skip data.
RC1REG;
} else {
if (uart_count < UART_BUFFER_SIZE) {
*wr_ptr = RC1REG;
uart_count++;
if (++wr_ptr >= &uart_buf[UART_BUFFER_SIZE]) wr_ptr = uart_buf;
} else RC1REG;
}
}
Поправил и кольцевой буфер, а то похоже, у меня на один байт дальше указатель вылетал. А объявлять локальную переменную в обработчике прерывания что-то желания нет. нет у меня доверия к этому компилятору в бесплатном режиме. Больше нет.
Еще вопрос. А как быть с EEPROM? как его проинициализировать? когда-то писал ORG 0x2000. А вот в С что-то не соображу. А до юзер мануала еще 3 часа ехать.
Re: Програмирование pic на СИ.
Добавлено: Ср мар 14, 2018 18:49:56
Аlex
uldemir писал(а):Cделал так:
Как вариант :
Код: Выделить всё
if (RCIE && RC1IF) {
if (!FERR && (uart_count < UART_BUFFER_SIZE)) {
*wr_ptr = RC1REG;
uart_count++;
if (++wr_ptr >= &uart_buf[UART_BUFFER_SIZE]) wr_ptr = uart_buf;
}
RC1REG;
}
По алгоритму получается один в один.
А
uart_count что делает ? И в какой момент сбрасывается ?
uldemir писал(а):нет у меня доверия к этому компилятору в бесплатном режиме.
А если сделать его "платным" ?

Какой компилятор, кстати ?
Если XC8, то на
uldemir писал(а):как быть с EEPROM? как его проинициализировать?
Мануал говорит следующее :
Re: Програмирование pic на СИ.
Добавлено: Ср мар 14, 2018 19:37:07
uldemir
Неплохой вариант. Я т пытался снахрапа взять. Собственно, еще одна ситуация не обрабатывается: OERR. Но, подумал, что это событие маловероятно, да и выход из него далеко не прост. Хотя, чё там не выключить и не включить обратно приём, раз уж данные и так потеряны?
uart_count у меня вычитается по мере считывания буфера в основном теле программы:
Код: Выделить всё
if (uart_count) { // в буфере есть данные.
uart_byte = *rd_ptr;
uart_count--;
if (++rd_ptr >= &uart_buf[UART_BUFFER_SIZE]) rd_ptr = uart_buf;
Может кольцевой буфер можно изящнее организовать? Надо посмотреть, как я сто лет назад его делал на 580-м процессоре...
Аlex писал(а):А если сделать его "платным" ?
да, это про XC8 - платный он дюже дорог. А триальными 60-ю днями я уже в прошлом году воспользовался и это счастье больше мне не светит. А обмануть, его можно было только до какой-то версии. Говорят, они теперь стали внутрь зашивать SHA256 файла проверяющего лицензию, поэтому подменить пустышкой его больше нельзя.
Re: Програмирование pic на СИ.
Добавлено: Ср мар 14, 2018 20:19:11
Аlex
А зачем гнаться за этими версиями ? Можно пользоваться той версией, до которой лекарство подходит. Вряд ли они что-то там серьёзное исправляют и добавляют.
Re: Програмирование pic на СИ.
Добавлено: Ср мар 14, 2018 21:09:06
oleg110592
xc8 1.41 в windows и свежая 1.45 в linux легко были обмануты пургеном от старой 1.32 версии 2014г.