»Радиолюбитель>PIC контроллеры. Программаторы и первый проект на PIC
petrd 21:43 26.01.2012
AlexVK
Код:
unsigned int temp2write; <- это какой тип?
........................................................
UART1_Write(temp2write); <- какой тип должен быть в скобках, а Вы какой засунули?
Это ж Си, в нем за приведением типов как бы программисту следить надо.
mishka123
Насчет зверя leaper-48. В руках не держал, но одно название УНИВЕРСАЛЬНЫЙ говорит о многом, он видимо не может ввести PIC в режим программирования (поэтому не может прочитать ID, поэтому и ошибка).
А насчет прошить PIC, пЫшите в личку.
[Ответ]
AlexVK 22:13 26.01.2012
Код:
unsigned int temp2write; <- это какой тип?
........................................................
UART1_Write(temp2write); <- какой тип должен быть в скобках, а Вы какой засунули?
Я пробовал уже объявлять переменную по разному-результат одинаков. Я не сомневаюсь, что я туплю, но не могу понять где и как. Во всех примерах переменная в основном инт, да и отправляют маленькие числа. Поэтому и прошу помощи у форума. Если можно кусочки кода отправки и приема данных.
[Ответ]
VRTP 02:11 27.01.2012
Сообщение от mishka123:
Друзья, помогите залить прошивку в контроллер. Есть сам контроллер, есть готовый HEX, нету программатора.
Паять программатор очень лень просто. Может есть тут добрые люди? А с меня пиво/сок/кефир - не вопрос.
Какой камень?
На верное смогу помочь,пиши в личку.
[Ответ]
Teeen 05:19 27.01.2012
Сообщение от AlexVK:
Код:
unsigned int temp2write; <- это какой тип?
........................................................
UART1_Write(temp2write); <- какой тип должен быть в скобках, а Вы какой засунули?
Я пробовал уже объявлять переменную по разному-результат одинаков. Я не сомневаюсь, что я туплю, но не могу понять где и как. Во всех примерах переменная в основном инт, да и отправляют маленькие числа. Поэтому и прошу помощи у форума. Если можно кусочки кода отправки и приема данных.
В helpe же примеры есть...
Код:
//------------------------------------------------------------------------------------------
unsigned char _data = 0x1E;
...
UART1_Write(_data);
//------------------------------------------------------------------------------------------
UART1_Init(4800); // initialize UART1 module
Delay_ms(100);
while (1) {
if (UART1_Data_Ready() == 1) { // if data is received
UART1_Read_Text(output, "OK", 10); // reads text until 'OK' is found
UART1_Write_Text(output); // sends back text
}
}
petrd, здравствуйте!
Подскажите пожалуйста, каким образом (просто) реализовать следующую функцию с помощью PIC:
"PWRKEY button – turns on the MOD-GSM module. You can turn on the SIM340D
by driving the PWRKEY to a low level voltage for period time from 500mS to 1S"
Т.е. мне нужно иммитировать нажатие кнопки ножкой МК.
[Ответ]
AlexVK 08:55 27.01.2012
Teeen,
Здравствуйте, а нельзя-ли на моем примере показать реализацию отправки temp2write,
получение в другом МК данных и преобразование их в переменную типа int
[Ответ]
P.S. Короче такую хитрость делать нельзя, т.к. если messag[0] или messag[0] будут равны 0, то для UART1_Write_Text(messag) это будет терминальный ноль и передачи вообще не будет (messag[0]=0) или будет передан всего один байт (messag[1]=0).
ИМХО, делать через обычный UART1_Write() и таймаут на прием.
[Ответ]
Нет не идет, показания на ЖК другие, но не правильные.
раньше показывал не правильно, но показания менялись равномерно, теперь скачут не предсказуемо
во вложении проекты и файл протеуса, может кто из интереса посмотрит и укажет верный путь
Изображения
Сообщение от Teeen: petrd, здравствуйте!
Подскажите пожалуйста, каким образом (просто) реализовать следующую функцию с помощью PIC:
"PWRKEY button – turns on the MOD-GSM module. You can turn on the SIM340D
by driving the PWRKEY to a low level voltage for period time from 500mS to 1S"
..........
Т.е. мне нужно иммитировать нажатие кнопки ножкой МК.
Вывод порта контроллера в приведенной схеме подключить к выводу PWRKEY.
Дальше (например, для RB0)
1. TRISB0 = 1
2. RB0 = 0
3. Когда надо нажать кнопку делаете TRISB = 0
4. Задержка от 0,5 до 1 сек
5. TRISB = 1.
[Ответ]
petrd 11:27 28.01.2012
Сообщение от AlexVK: petrd,
Нет не идет, показания на ЖК другие, но не правильные.
раньше показывал не правильно, но показания менялись равномерно, теперь скачут не предсказуемо
во вложении проекты и файл протеуса, может кто из интереса посмотрит и укажет верный путь
Со строками путь не совсем правильный. Смотрите другой вариант во вложении.
Изображения
Спасибо, все работает. Ну уж раз пошла такая пьянка, разрешите еще вопрос, а если надо с этими двумя байтами передать еще и любое произвольное число от, ну скажем от 0 до 20, или скажем еще один байт
[Ответ]
AlexVK 18:06 28.01.2012
Петр, Вы открывали эту тему с целью научить нас программировать PIC с нуля. Большое Вам спасибо. на этом форуме я на самом деле узнал много нового( в принципе для меня практически все новое и интересное) Прошу Вас продолжить в том же направлении. В данном случае у меня была проблема с UART, с Вашей помощью частная задача решена, все работает. Но хотелось бы узнать все поподробнее. Я думаю это направление многим начинающим будет очень интересно. Если можно популярно объяснить эту тему от простого к более сложному. Передача и прием одного, двух и более байт, вставка в передачу служебной информации, коллич. байт, адрес, подсчет и передачу контрольной суммы.
[Ответ]
Feo787 19:40 29.01.2012
Господа!
В начале темы в 2009 году рассматривался вопрос работы с DS18B20. Хотел бы снова поднять данный вопрос.
Крайне интересует работа с несколькими датчиками на одной линии.
Если у кого-нибудь есть примеры кода на MikroC буду крайне признателен.
Большое спасибо!
[Ответ]
petrd 21:52 29.01.2012
По просьбе здесь буду писать про UART. Пересказывать datasheet не буду.
Некоторые особенности приемного модуля в PIC в асинхронном режиме (на пальцах):
1. Модуль имеет двойной приемный буфер (FIFO). Смысл такой - как только определен стоп-бит, принятый байт сваливается вверх буфера FIFO. Если буфер не вычитывать, то следующий принятый байт попадет вниз буфера FIFO. Если и после второго принятого байта не вычитывать буфер, то по приему стоп-бита третьего байта будет выставлен флаг OERR (это значит - принято три байта, после чего работа приемника остановлена, в буфере FIFO находятся два байта и их можно прочитать, третий байт будет утерян). Чтобы возобновить работу модуля потребуется выключить приемник и снова его включить (CREN = 0; CREN = 1; ). Чтобы этого не происходило надо своевременно вычитывать данные из FIFO. Своевременно - это значит до прихода стоп-бита третьего байта. Это делается чтением регистра RCREG. О том, что в буфере FIFO есть принятые данные сообщает бит RCIF = 1. Если все данные вычитаны RCIF будет установлен в 0 (аппаратно). Если по какой-то причине передающее устройство прекратило передачу посреди байта и приемник своевременно не обнаружил стоп-бита, то будет установлен флаг FERR = 1. Если есть необходимость проверять этот флаг, то его надо проверять перед чтением регистра RCREG (смысл такой: если FERR не установлен, то байт принят полностью, поэтому можно читать RCREG). Также появление FERR может проявляться в случае, когда не совпадают скорости приемника и передатчика.
2. Случаи, когда вся полезная информация передается в одном байте большая редкость. Практически всегда для передачи информации одного байта мало, байтов требуется больше чем один. Т.е. нужны пакеты из байтов, а передавать их надо по асинхронному каналу, т.е. без специальных мер никогда заранее не известно в какой момент начнется передача пакета, был ли перерыв в передаче пакета, закончена ли передача пакета. Пример: допустим мы знаем, что пакет состоит из пяти байт. Сначала включили приемник, а потом передатчик. В итоге считается количество принятых байтов и как только их принято пять, то делается вывод, что пакет принят. Вроде все как надо. А если сначала начать передачу, а потом включить приемник? Пять байтов-то будет принято, но не факт, что они из одного пакета. Пример засады - код из поста №941 (в протеусе-то работает, а в реальности могут возникнуть проблемы). Поэтому и нужны эти самые "специальные меры".
Про пакеты. Пакеты могут быть фиксированной и переменной длины. Для пакетов фиксированной длины важно определить начало пакета, а конец высчитывается легко. Для пакетов переменной длины сложнее, информация о длине пакета должна быть заложена внутри пакета. Если известно начало - то конец найдется.
Вариант. Есть такой протокол Modbus в двух вариантах передачи данных Modbus RTU и Modbus ASCII. В Modbus RTU оговорено, что время между пакетами не может меньше, чем 3,5 фрейма (где фрейм - это старт-бит + 8 бит данных + бит четности + стоп-бит и т.п.). Т.е. если нет обмена в течении времени больше чем 3,5 фрейма, то можно утверждать, что первый принятый байт после этого интервала тишины будет началом пакета. Алгоритм реализации примерно такой: прием байта идет в прерывании, байты складываются в буфер, также имеется таймер, настроенный на 3,5 фрейма. При приеме байта, таймер сбрасывается. Если сработал таймер, а перед этим принимался пакет, то считается, что прием пакета закончен, а сам пакет находится в буфере.
Некоторые макросы:
Код:
//макрос инициализации USART
#define USART_INIT(spbrg) \
SPBRG = (spbrg); \
TXSTA = 0b10010100; \
RCSTA = 0b10000000; \
TXEN_bit = 1;
//макрос отправки байта через USART
#define SENDBYTE(b) while(!TXIF_bit); \
TXREG = (b)
// В программе перед началом соединения инициализируем USART
// USART_INIT(bRate); //bRate - скорость связи - читаем даташит :)
// USART_INIT(10); // 57600 при Fosc = 10 МГц
// ...
// передаем байт
// SENDBYTE(bData); //bData - передаваемый байт
petrd,
Спасибо за новую тему, с нетерпение жду продолжения. Если можно с небольшими примерами, достаточно кусков кода передачи и приема. Особенно интересует передача и прием разрозненных данных. например МК считывает данные с датчика температуры и АЦП, после этого передает их второму МК, добавляя кое -что от себя, парочку любых чисел. Если будут 2-3 датчика температуры и 2-3 АЦП это вообще сказка. Заранее спасибо.
[Ответ]
Teeen 12:08 31.01.2012
petrd, здравствуйте! Подскажите пожалуйста, а то не могу понять причину, пишу в переменную ModemAnswer принятые байты и сразу же посылаю их обратно - все нормально, но после передачи, когда нажимаю кнопку, повешанную на RA1_bit хочу считать ранее принятые байты, то получается ерунда в ответе. Почему так? Из-за неверно используемой переменной ModemAnswer?
Код:
unsigned char *ModemAnswer[16]; // Ответ модема на команды
...
// Главный цикл
do {
if (!RA0_bit){Send2_SMS();} // Отправляем СМС
if (!RA1_bit){ // Читаем ответ модема
UART1_Write_Text(ModemAnswer);
delay_ms(200);
}
if (UART1_Data_Ready()==1){
receive=UART1_Read();
if (receive != 0x0D && receive != 0x0A){
i++;
ModemAnswer[i]=receive;
UART1_Write(ModemAnswer[i]);
}
}
else{i=0;}
}// end do
while (1);
}// end main
//------------------------------------------------------------------------------
Сообщение от petrd:
Итак, первый реальный проект из разряда "Hello World".
1. Создаем папку C:\PROJECT\MikroC, в ней и будем создавать проект.
2. Открываем Mikroc и идем Project -> New Project.
3. В открывшемся окне
- даем имя проекту - Project Name пишем Test_PIC16F628A
- указываем путь - Project Path пишем C:\PROJECT\MikroC или ищем путь через Browse
- Description - ничего не пишем
- Device - выбираем PIC16F628A
- Clock вставляем 004.000000
- Device Flags - ставим галки напротив WDT_OFF, LVP_OFF, MCLRE_ON, INTOSC_OSC_NOCLCOUT, осталные должны быть без галок.
Нажимаем OK.
Тем самым установили конфигурацию МК - тактовая частота 4 МГц, сторожевой таймер отключен, низковольтовое программирование отключено,
вывод MCLR будем использовать для внешнего сброса, тактовый генератор внутренний, тактовый сигнал наружу выводиться не будет.
Далее в главном окне с именем Test_PIC16F628A.c пишем
Код:
void main()
{
TRISB=0; // настроили выводы PORTB на вывод
while(1){ // организовали вечный цикл
PORTB=~PORTB; // инверсия уровней на выводах PORTB
delay_ms(1000); // задержка на 1000 мс = 1 сек
}
}// main
Все можно компилировать. Нажимаем на шестеренки с подсветкой BuildProject (Ctrl+F9). Если все без ошибок, то в нижнем окне видим три строчки,
в верхней должно быть Success (Release Build), в двух нижних показано количество используемой памяти программ и памяти данных и свободной памяти.
После удачной компиляции в папке C:\PROJECT\MikroC будут находиться все файлы данного проекта, в том числе и файл прошивки Test_PIC16F628A.hex.
Если прошить МК данным файлом, то получим мигание 8-и светодиодов (по приведенной схеме) с периодом 1 сек.
P.S. Практически бесполезный проект, но пригодный для начального опыта. Проверен в реальном железе.
Схема под данный проект. Вопросы задаем, обсуждаем.
Недопонимаю чего-то. Разве так должно быть? Весь порт должен синхронно мигать. А тут ...
Изображения
Попробуй вот так, в начальных настройках надо записать в PORTB 0 или 1, надо конкретно указывать, иначе там может быть что угодно, поэтому у Вас и нет синхронного мигания всего порта
Код:
void main()
{
TRISB=0; // настроили выводы PORTB на вывод
PORTB=0; // записали в PORTB 0
while(1){ // организовали вечный цикл
PORTB=~PORTB; // инверсия уровней на выводах PORTB
delay_ms(1000); // задержка на 1000 мс = 1 сек
}
}// main
unsigned int i, y;
//------------------------------------------------------------------------------
// Инициализируем UART
UART1_Init(9615); // Initialize hardware UART1 and establish communication at 9600 bps
прием)
Delay_ms(100); // Задержка для инициализации UART
//------------------------------------------------------------------------------
// Основная программа
void main() {
char recieve;
char ModemAnswer[20]; // Ответ модема на команды
Init(); // Запускаем процедуру инициализации
Lcd_Out(1, 1, "I am ready!"); // Отображаем приветствие
i=0;
// Главный цикл
do {
if (!RA0_bit){Send_CMD();} // Отправляем СМС
if (!RA1_bit){ // Читаем ответ модема
LCD_Out(2,1," ");
for (y=0;y<i;y++){
//UART1_Write(ModemAnswer[y]); //НЕ ЗАБЫВАТЬ КОММЕНТТИРОВАТЬ для модема!!!
LCD_Chr(2,y+1,ModemAnswer[y]);
//LCD_Chr(2,1,0x30+i);
}
delay_ms(200);
i=0;
}
if (UART1_Data_Ready()==1){
ModemAnswer[i]=UART1_Read();
i++;
}
}// end do
while (1);
}// end main
//------------------------------------------------------------------------------
Отлаживал с помощью PICkit2 (ч/з UART Tool)
Данные отправляются и принимаются четко как в аптеке... НО!
Когда соединил PIC с модемом (модем сам настраивается на скорость обмена по Datasheet), то данные отправляются четко и модем отсылает, например СМС, но если попробовать получить результат выполнения команды модемом, мой PIC принимает ч/з UART не то что ожидается...
Причем соединялся с модемом также ч/з PICkit2 - на команду "AT"+<CR> модем четко возвращает АT<CR><CR><LF>OK<CR><LF>, т.е. полученную команду и ответ на нее "ОК".
Мой PIC16F877A возвращает первый раз "AT", когда второй раз посылаешь команду "АТ" в модем - PIC возвращает "PU" - и дальше, сколько бы я не отправлял команду "AT" в модем - PIC возвращает "PU"?
Пробовал играться скоростями - не помогает.
Явную причину пока определить не могу, но есть сомнения, что это может быть связано с 9-и разрядным приемом данных UART PIC (как посмотреть функцию UART1_Init()?)
Еще заметил, что от модема ответ приходит всегда не больше 2-х байт?
Возможно еще, что модем шлет ответ с другой скоростью, чем инициирован UART PIC?
Помогите пожалуйста, я уже плюнул на встроенные библиотеки по работе с UART, сейчас изучаю как самому инициализировать его и запустить...
Очень жду ваших советов...
[Ответ]
BARS_21 19:49 03.02.2012
Сообщение от AlexVK:
Попробуй вот так, в начальных настройках надо записать в PORTB 0 или 1, надо конкретно указывать, иначе там может быть что угодно, поэтому у Вас и нет синхронного мигания всего порта
Код:
void main()
{
TRISB=0; // настроили выводы PORTB на вывод
PORTB=0; // записали в PORTB 0
while(1){ // организовали вечный цикл
PORTB=~PORTB; // инверсия уровней на выводах PORTB
delay_ms(1000); // задержка на 1000 мс = 1 сек
}
}// main
Точно, теперь работает так, как и ожидал. Спасибо!
[Ответ]
otest 22:17 03.02.2012
Вы что не можите встретиться и обговорить свои проблемы ?
[Ответ]
AlexVK 23:08 03.02.2012
petrd,
Пожалуйста продолжайте, Вы подошли к самому интересному.
Сообщение от otest:
Вы что не можите встретиться и обговорить свои проблемы ?
По моему мы здесь и обговариваем свои проблемы. , форум для этого и существует.
[Ответ]
Teeen 15:50 10.02.2012
Написал по Datasheet к PIC16F877A асинхронный приемо-передатчик, получил результат такой же как и для существующих функций в MikroC - USARTx_Read() - приведенной выше в коде.
Но мне удалось найти причину, при приеме от модема всегда принимается только один байт и сразу возникает ошибка OERR, причем скорость модема я устанавливаю с помощью PICKit2 (USART tool) и после перезагрузки модема скорость всегда 9600бод. (Проверил.)
Если посылаю данные ч/з PICKit2 в PIC или модем - данные принимаются четко и ошибка не возникает...
Что думаю, возможно модем посылает байты без задержек м/у ними, а программа просто не успевает считывать RCREG? PIC работает на частоте 16Мгц. Пробовал повысить скорость приема UART PIC - вместо 9615бод поставил 19231, то данные стали приходить без мусора, но ошибка переполнения продолжает возникать после приема первого байта. Уже подумываю увеличить длину кабеля м/у PIC и модемом для увеличения задержки в передачи данных, поможет или нет?
Я так понимаю, что когда мы перегружаем UART:
Код:
CREN_bit=0;
CREN_bit=1;
следующие данные пересланные модемом теряются и в целом ответ модема получить невозможно.
Что имеем: BRGH=1
SPBRG=103 (бывает мусор), SPBRG=51 - 2-а байта принимаются без мусора (в обоих случаях имеем ошибку OERR)...
Внимание всем вопрос: кто виноват и что делать? [Ответ]
petrd 21:26 10.02.2012
Не надо скорости UART подстраивать - есть стандартный ряд вот им и надо пользоваться (....... 9600, 19200, ....). Вот эти Ваши подстройки 9615, 19231 точно на конечный результат не влияют. Для 16 МГц и 9600 все правильно настроено (BRGH=1; SPBRG=103) и мусор тут от неправильной программы или железа. И не надо провода удлиннять, фигней не занимайтесь.
Как вариант - сделать прерывания по приему (RCIF) и кольцевой буфер. В прерывании принимаемые данные будут быстро выбиратьсяся из RCREG и складываться в буфер, а в основной программе выбираться из буфера и обрабатываться.
[Ответ]
Teeen 12:47 11.02.2012
petrd, спасибо! Во вторник перепишу прием данных ч/з прерывание... Отпишусь потом что получилось...
[Ответ]
VLV89 22:12 13.02.2012
Здравствуйте!
Ребят ну не пинайте сильно меня, пока только начинаю осваивать, есть огромное желание научиться програмировать микроконтроллеры. Спаять могу впринципе, а вот со схемами и компонентами пока не силён. Хочу собрать pic программатор сам, вот нашёл в интернете схему, подскажите пожалуйста все ли я компоненты перечислил, которые нужны для его сборки:
Светодиод - 1шт
панелька dip18 - 1шт
Com port 9 pin ( мама) - 1шт
Еще пара вопросиков:
1. Все ли беспроблемно можно найти?
2. Не пойму зачем там переменный резистор.
3. Какую мощность резисторов брать? 0.25 будет достаточно? или как вообще определять нужную мощность.
Не переводи силы ,время и деньги на это г-о
[Ответ]
VLV89 22:43 13.02.2012
Сообщение от otest:
Не переводи силы ,время и деньги на это г-о
Да тут понимаешь, просто хочется с чего то начать, чтобы так сказать на практике получилось, чтоб вставить прошить, а оно заработало))))) потом уже двигаться дальше Понимаю, что можно купить готовый программатор, но еще раз повторюсь, хочу попрактиковаться с положительным эффектом [Ответ]