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

Поклонники продукции Microchip Technology Inc тусуются тут.
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

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

Сообщение SpeedFighter »

Да, с этим уже разобрался, спасибо!

А как перевести из float в int / unsigned int?

2.5*(5.0*ADRESH/(256.0)) - 1.0; - Вот это хотел бы перевести в int.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25159
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

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

Вы занимаетесь отчаянной ерундой.
Никакого флоата не требуется.
Вы пытаетесь считать на МК как на калькуляторе. Это совершенно пустое мероприятие.
Для чего Вам нужны вольты?
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

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

Сообщение SpeedFighter »

Поясняю, для чего:

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

0,4 В - 0
0,8 В - 1
и так далее.

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

P.S. Есть гайд небольшой, по работе с LCD? (lm016l - если конкретно).
Последний раз редактировалось SpeedFighter Сб дек 16, 2017 22:41:33, всего редактировалось 1 раз.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25159
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

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

Это апокалиптический бред.
Вместо внятного дефайна константы сравнения Вы считаете никому не нужный флоат.
Уважаемый, Вам бы основы программирования почитать, прежде чем писать код...
ЗЫ. Вывод на дисплей тоже не требует флоата. На дисплей выводят ДВОИЧНО-ДЕСЯТИЧНОЕ ЦЕЛОЕ ЧИСЛО, а не флоат. Точку зажигают в необходимой позиции независимо от расчета цифр в разрядах.
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

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

Сообщение SpeedFighter »

Понял, ладно.

Но библиотеку для работы с LCD все равно не могу найти для PIC.
Аватара пользователя
КРАМ
Друг Кота
Сообщения: 25159
Зарегистрирован: Чт янв 10, 2008 22:01:02
Откуда: Московская область, Фрязино

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

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

А к чему она?
Есть даташит на ЖК, вот и напишите драйвер сами.
SpeedFighter
Открыл глаза
Сообщения: 63
Зарегистрирован: Вс май 28, 2017 19:07:32

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

Сообщение 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, но это задержки тут кривые, наверное.
Аватара пользователя
xterro
Опытный кот
Сообщения: 873
Зарегистрирован: Чт апр 12, 2012 07:19:59
Откуда: Тюмень

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

Сообщение xterro »

Что скажете по поводу компилятора sdcc? Он вроде как умеет pic16/18 и бесплатный?
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение 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;
            }
        }
    }
Последний раз редактировалось uldemir Вт мар 13, 2018 18:54:17, всего редактировалось 1 раз.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
driver_gv
Потрогал лапой паяльник
Сообщения: 399
Зарегистрирован: Сб авг 08, 2009 23:02:57
Откуда: Ростов-на-Дону
Контактная информация:

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

Сообщение driver_gv »

Может надо RCREG1 ? и что пишет то при компиляции?
__________________
Все, что нельзя запрограммировать на ассемблере, приходится паять
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Перед знаком "=" всегда должен стоят "адресат".
Просто прочитать можно написав имя регистра без всяких лишних знаков.

Добавлено after 3 minutes 25 seconds:
А вообще, в Вашем коде можно сделать чтение регистра во временную переменную, вначале условия, а потом уже работать с ней. Т.к. :
1. Он в коде у Вас 2 раза читается.
2. Компилятор, в любом случае, выделит место для его чтения.
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

Не читается - второе под условием else - будет или один или второй. Думал, может кто замечание по реализации кольцевого буффера скажет... чёрт, вижу еще один затык: если буфер переполнен, то я тоже не читаю регистр, а флаг прерывания снимаю - тоже может повиснуть и не отвиснуть.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Вы, по всей видимости, меня не поняли.

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

    if (RCIE && RC1IF) {
        unsigned char rcreg=RC1REG;
        ..............
        ..............
И дальше читаем переменную rcreg где нужно. А RC1REG будет прочитан всегда, когда вызовется прерывание.

Добавлено after 4 minutes 17 seconds:
Кстати, RC1IF = 0; - бесполезное действие. Он сбрасывается аппаратно, при чтении регистра RCREG.
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

спасибо за подсказку по поводу флага прерывания. а по поводу ошибки фрейма - так делать нельзя. флаг надо проверить до считывания регистра. и сбрасывать его как я пытался - тоже нельзя - он только читается.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Тогда сделайте так, да и всё :

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

        if(FERR) {
            unsigned char rcreg=RC1REG;
        } else {

А остальное оставьте как есть.

PS: Проц какой ?
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение 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 часа ехать.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение А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 писал(а):нет у меня доверия к этому компилятору в бесплатном режиме.
А если сделать его "платным" ? :roll:
Какой компилятор, кстати ?
Если XC8, то на
uldemir писал(а):как быть с EEPROM? как его проинициализировать?
Мануал говорит следующее :
Изображение
2018-03-14_19-52-34.png
(25.71 КБ) 593 скачивания
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение 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 файла проверяющего лицензию, поэтому подменить пустышкой его больше нельзя.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

А зачем гнаться за этими версиями ? Можно пользоваться той версией, до которой лекарство подходит. Вряд ли они что-то там серьёзное исправляют и добавляют.
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

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

Сообщение oleg110592 »

xc8 1.41 в windows и свежая 1.45 в linux легко были обмануты пургеном от старой 1.32 версии 2014г.
Ответить

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