Програмирование pic на СИ.
-
SpeedFighter
- Открыл глаза
- Сообщения: 63
- Зарегистрирован: Вс май 28, 2017 19:07:32
Re: Програмирование pic на СИ.
Да, с этим уже разобрался, спасибо!
А как перевести из float в int / unsigned int?
2.5*(5.0*ADRESH/(256.0)) - 1.0; - Вот это хотел бы перевести в int.
А как перевести из float в int / unsigned int?
2.5*(5.0*ADRESH/(256.0)) - 1.0; - Вот это хотел бы перевести в int.
- КРАМ
- Друг Кота
- Сообщения: 25156
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Програмирование pic на СИ.
Вы занимаетесь отчаянной ерундой.
Никакого флоата не требуется.
Вы пытаетесь считать на МК как на калькуляторе. Это совершенно пустое мероприятие.
Для чего Вам нужны вольты?
Никакого флоата не требуется.
Вы пытаетесь считать на МК как на калькуляторе. Это совершенно пустое мероприятие.
Для чего Вам нужны вольты?
-
SpeedFighter
- Открыл глаза
- Сообщения: 63
- Зарегистрирован: Вс май 28, 2017 19:07:32
Re: Програмирование pic на СИ.
Поясняю, для чего:
Я через вольты написал приблизительную функцию для нажатой клавиши:
0,4 В - 0
0,8 В - 1
и так далее.
Но увы, придется нажатие клавиш разных чисто через ADRESH обрабатывать, что некрасиво, увы.
P.S. Есть гайд небольшой, по работе с LCD? (lm016l - если конкретно).
Я через вольты написал приблизительную функцию для нажатой клавиши:
0,4 В - 0
0,8 В - 1
и так далее.
Но увы, придется нажатие клавиш разных чисто через ADRESH обрабатывать, что некрасиво, увы.
P.S. Есть гайд небольшой, по работе с LCD? (lm016l - если конкретно).
Последний раз редактировалось SpeedFighter Сб дек 16, 2017 22:41:33, всего редактировалось 1 раз.
- КРАМ
- Друг Кота
- Сообщения: 25156
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Програмирование pic на СИ.
Это апокалиптический бред.
Вместо внятного дефайна константы сравнения Вы считаете никому не нужный флоат.
Уважаемый, Вам бы основы программирования почитать, прежде чем писать код...
ЗЫ. Вывод на дисплей тоже не требует флоата. На дисплей выводят ДВОИЧНО-ДЕСЯТИЧНОЕ ЦЕЛОЕ ЧИСЛО, а не флоат. Точку зажигают в необходимой позиции независимо от расчета цифр в разрядах.
Вместо внятного дефайна константы сравнения Вы считаете никому не нужный флоат.
Уважаемый, Вам бы основы программирования почитать, прежде чем писать код...
ЗЫ. Вывод на дисплей тоже не требует флоата. На дисплей выводят ДВОИЧНО-ДЕСЯТИЧНОЕ ЦЕЛОЕ ЧИСЛО, а не флоат. Точку зажигают в необходимой позиции независимо от расчета цифр в разрядах.
-
SpeedFighter
- Открыл глаза
- Сообщения: 63
- Зарегистрирован: Вс май 28, 2017 19:07:32
Re: Програмирование pic на СИ.
Понял, ладно.
Но библиотеку для работы с LCD все равно не могу найти для PIC.
Но библиотеку для работы с LCD все равно не могу найти для PIC.
- КРАМ
- Друг Кота
- Сообщения: 25156
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Програмирование pic на СИ.
А к чему она?
Есть даташит на ЖК, вот и напишите драйвер сами.
Есть даташит на ЖК, вот и напишите драйвер сами.
-
SpeedFighter
- Открыл глаза
- Сообщения: 63
- Зарегистрирован: Вс май 28, 2017 19:07:32
Re: Програмирование pic на СИ.
Мне так удобнее было бы разобраться.
Так-то вот, нашел один код, который я в проект свой вставил:
Жаль только, что что слишком часто сменяются надписи Ok и Test, но это задержки тут кривые, наверное.
Так-то вот, нашел один код, который я в проект свой вставил:
Спойлер
Код: Выделить всё
/*
* 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 ; // Метка начала преобразования
}
Re: Програмирование pic на СИ.
Что скажете по поводу компилятора sdcc? Он вроде как умеет pic16/18 и бесплатный?
Re: Програмирование pic на СИ.
ниид хелп. Компилятор XC8 не хочет проглатывать такую простую конструкциюМне нужно его просто прочитать, но данные сохранять не нужно. Почему-то казалось, что это вполне легальная конструкция.
Код: Выделить всё
=RC1REGСпойлер
контекст:Код: Выделить всё
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 на СИ.
Может надо RCREG1 ? и что пишет то при компиляции?
__________________
Все, что нельзя запрограммировать на ассемблере, приходится паять
Все, что нельзя запрограммировать на ассемблере, приходится паять
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Програмирование pic на СИ.
Перед знаком "=" всегда должен стоят "адресат".
Просто прочитать можно написав имя регистра без всяких лишних знаков.
Добавлено after 3 minutes 25 seconds:
А вообще, в Вашем коде можно сделать чтение регистра во временную переменную, вначале условия, а потом уже работать с ней. Т.к. :
1. Он в коде у Вас 2 раза читается.
2. Компилятор, в любом случае, выделит место для его чтения.
Просто прочитать можно написав имя регистра без всяких лишних знаков.
Добавлено after 3 minutes 25 seconds:
А вообще, в Вашем коде можно сделать чтение регистра во временную переменную, вначале условия, а потом уже работать с ней. Т.к. :
1. Он в коде у Вас 2 раза читается.
2. Компилятор, в любом случае, выделит место для его чтения.
Re: Програмирование pic на СИ.
Не читается - второе под условием else - будет или один или второй. Думал, может кто замечание по реализации кольцевого буффера скажет... чёрт, вижу еще один затык: если буфер переполнен, то я тоже не читаю регистр, а флаг прерывания снимаю - тоже может повиснуть и не отвиснуть.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Програмирование pic на СИ.
Вы, по всей видимости, меня не поняли.
И дальше читаем переменную rcreg где нужно. А RC1REG будет прочитан всегда, когда вызовется прерывание.
Добавлено after 4 minutes 17 seconds:
Кстати, RC1IF = 0; - бесполезное действие. Он сбрасывается аппаратно, при чтении регистра RCREG.
Код: Выделить всё
if (RCIE && RC1IF) {
unsigned char rcreg=RC1REG;
..............
..............
Добавлено after 4 minutes 17 seconds:
Кстати, RC1IF = 0; - бесполезное действие. Он сбрасывается аппаратно, при чтении регистра RCREG.
Re: Програмирование pic на СИ.
спасибо за подсказку по поводу флага прерывания. а по поводу ошибки фрейма - так делать нельзя. флаг надо проверить до считывания регистра. и сбрасывать его как я пытался - тоже нельзя - он только читается.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Програмирование pic на СИ.
Тогда сделайте так, да и всё :
А остальное оставьте как есть.
PS: Проц какой ?
Код: Выделить всё
if(FERR) {
unsigned char rcreg=RC1REG;
} else {
PS: Проц какой ?
Re: Програмирование pic на СИ.
pic18f25k40. Cделал так:
Поправил и кольцевой буфер, а то похоже, у меня на один байт дальше указатель вылетал. А объявлять локальную переменную в обработчике прерывания что-то желания нет. нет у меня доверия к этому компилятору в бесплатном режиме. Больше нет.
Еще вопрос. А как быть с EEPROM? как его проинициализировать? когда-то писал ORG 0x2000. А вот в С что-то не соображу. А до юзер мануала еще 3 часа ехать.
Код: Выделить всё
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 на СИ.
Как вариант :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 на СИ.
Неплохой вариант. Я т пытался снахрапа взять. Собственно, еще одна ситуация не обрабатывается: OERR. Но, подумал, что это событие маловероятно, да и выход из него далеко не прост. Хотя, чё там не выключить и не включить обратно приём, раз уж данные и так потеряны?
uart_count у меня вычитается по мере считывания буфера в основном теле программы:
Может кольцевой буфер можно изящнее организовать? Надо посмотреть, как я сто лет назад его делал на 580-м процессоре...
uart_count у меня вычитается по мере считывания буфера в основном теле программы:
Код: Выделить всё
if (uart_count) { // в буфере есть данные.
uart_byte = *rd_ptr;
uart_count--;
if (++rd_ptr >= &uart_buf[UART_BUFFER_SIZE]) rd_ptr = uart_buf;да, это про XC8 - платный он дюже дорог. А триальными 60-ю днями я уже в прошлом году воспользовался и это счастье больше мне не светит. А обмануть, его можно было только до какой-то версии. Говорят, они теперь стали внутрь зашивать SHA256 файла проверяющего лицензию, поэтому подменить пустышкой его больше нельзя.Аlex писал(а):А если сделать его "платным" ?
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Програмирование pic на СИ.
А зачем гнаться за этими версиями ? Можно пользоваться той версией, до которой лекарство подходит. Вряд ли они что-то там серьёзное исправляют и добавляют.
- oleg110592
- Друг Кота
- Сообщения: 3832
- Зарегистрирован: Сб сен 10, 2011 17:46:25
Re: Програмирование pic на СИ.
xc8 1.41 в windows и свежая 1.45 в linux легко были обмануты пургеном от старой 1.32 версии 2014г.