Если это ваш первый визит, рекомендуем почитать справку по форуму. Для размещения своих сообщений необходимо зарегистрироваться. Для просмотра сообщений выберите раздел. |
PIC контроллеры. Программаторы и первый проект на PIC |
Программирование микроконтролеров,ремонт аудио/видео/бытовой техники,полезные устройства для дома,телефония, обсуждение статей журнала Радио |
|
Опции темы |
26.03.2009, 19:56 | #31 | |
///
Сообщений: 9,724
Регистрация: 02.04.2005
Возраст: 43
Не в сети |
Цитата:
Сколько раз у меня были ситуации, когда хотелось винить во всем кривой компилятор, мол я пишу все правильно, значит должно работать. Но потом выяснялось, что виноват был я. Что касается коротких временных интервалов - писал как-то раз программу в которой приходилось контроллировать количество тактов, за которое выполняется какой либо участок кода - запускал таймер, выводил на экран количество тиков - никакой нестабильности не замечал. А если программа требует реализации сложных структур, меню на дисплейчике например - как такое написать на ASM? а потом еще и отлаживать? |
|
27.03.2009, 06:55 | #32 |
Форумец
|
Все неисправности (bugs) выявленные в конкретном контроллере описаны в специальном документе под названем Errata, в нем же описан обход (Work around). А самая главная неисправность, известная мне, это кривые руки + кривая программа. Сами по себе PIC контроллеры очень живучие и надо немало постараться, чтобы его убить (если, конечно, не специально убивать).
|
27.03.2009, 12:01 | #33 |
Форумец
|
Тот же проект со светодиодами, но немного по-другому.
В предыдущей программе практически все процессорное время уходило на программный отсчет задержки и в течении 1 сек. контроллер уже ничего не мог делать. Для того чтобы избавить контроллер от такой рутины будем использовать аппаратные средства контроллера: механизм прерываний и один из таймеров (TMR0). Максимальное время, которое может отсчитать TMR0 при тактовой частоте 4 МГц равняется примерно 66,304 mS, а если 66,304*15 = 994,56 mS, то есть почти секунда. Вот и будем в каждом 15-м прерывании изменять состояние уровней PORTB на противоположное. Для расчета значений использовал программу PIC Timer Calculator скачать можно здесь http://pictimer.picbingo.com/download/index.php. Код:
unsigned short counter; void interrupt(){ if(INTCON.T0IF){ counter++; if (counter>14){ PORTB=~PORTB; // инверсия уровней на выводах PORTB counter=0; } INTCON.T0IF=0; } }// interrupt void Init(){ TRISB=0; // настроили выводы PORTB на вывод OPTION_REG = 0x87; // настройка TMR0, прерывания будут каждые 66,304 ms INTCON.T0IE=1; // разрешили прерывания по переполнению TMR0 INTCON.GIE=1; // включили механизм прерываний }// Init void main(){ Init(); while(1){ // организовали вечный цикл // теперь здесь можно что-то делать, а светодиоды все равно будут моргать 1 раз в секунду } }//~ Последний раз редактировалось petrd; 27.03.2009 в 12:14. |
27.03.2009, 15:29 | #35 |
Registered User
Сообщений: 391
Регистрация: 16.11.2008
Не в сети |
|
27.03.2009, 15:51 | #36 |
Форумец
|
|
27.03.2009, 21:23 | #37 |
Форумец
Сообщений: 69
Регистрация: 10.12.2006
Возраст: 58
Не в сети |
petrd, СПАСИБО за http://pictimer.picbingo.com/download/index.php. давно такое искал а то приходилось голову ломать
|
28.03.2009, 19:49 | #38 |
Форумец
Сообщений: 175
Регистрация: 19.08.2007
Не в сети |
petrd, спасибо за тему, очень актуально. вопрос - по книге Шпака Ю.А. реально освоить С самостоятельно? с монитора читать несколько неудобно, хотел в магазинах ее поискать. или можт еще кто чего посоветует для чайника в сях.
|
28.03.2009, 21:32 | #39 |
Форумец
|
Да, реально. Я Си самостоятельно осваивал (и было это не так давно) и при этом специально его не изучал. Если есть навыки программирования на любом языке, а главное желание, то проблем не вижу никаких.
Шпак - хорошая книга, но в продаже ее не видел никогда, я ее кусками печатал, да всю ее и не надо. Одно НО, в ней описывается компилятор Си - CCS (я говорю только за PIC), но он не очень-то распростанен (хотя Си он и в Африке Си). Большая масса людей пишет на PICC от HI-Tech. А так книжка хорошая, но из нее быстро вырастаешь и тут уже нужна - БИБЛИЯ по Си (повторюсь) это Брайан Керниган и Деннис Ритчи "Язык программирования С" продается в книжных магазинах, надо только поискать. |
29.03.2009, 21:18 | #40 |
Форумец
|
Рассказ "Про TRIS, PORT и LAT или грабли на которые наступают начинающие"
Применительно к PIC16F628A имеется два полных 8-и разрядных порта - PORTA и PORTB. Они могут работать как на вход, так и на выход. Для этого имеются регистры управления направлением - TRISA (для PORTA) и TRISB (для PORTB). Например, если нулевой бит регистра TRISB установлен в 1, то вывод RB0 (нулевой бит PORTB) работает как вход, если бит установлен в 0, то работает как выход. Разработчики Microchip рекомендуют такие ассоциации: "1" похожа на букву "I", первую букву слова Input (вход), ноль - похож на букву O, первую букву слова Output (выход). Вывод в порт: Код:
TRISB=0; // все выводы PORTB настроили на вывод PORTB=0xff; // на всех выводах PORTB будут единички Код:
TRISB=0xff; // все выводы PORTB на вход i=PORTB; // в переменной i будет сохранено значение считанное с выводов PORTB. Окончание этого рассказа следует. |
30.03.2009, 08:38 | #41 |
Форумец
|
Продолжение рассказа "Про TRIS, PORT и LAT или грабли на которые наступают начинающие".
Так вот начинающие часто забывают (или не знают), что порты PIC16 это не совсем регистры, и пытаются с ними работать, как с регистрами. Что пытаются делать? Например, если взять примеры по морганию светодиодами, нам надо погасить один светодиод, в то время как остальные должны продолжать светиться. В MikroC есть команды по установке в 0 или 1 отдельных бит регистра (PORTB.F0=0 или PORTB.F0=1 соответственно), которые эквивалентны командам ассемблера BCF и BSF. Вот этими командами и пытаются погасить или зажечь нужный светодиод, а в результате можно получить, что начинают гаснуть или зажигаться еще и другие светодиоды. Хотя нужен был только один выбранный. В чем же дело? А дело в том, что запись производится по принципу Чтение-Модификация-Запись (RMW - Read_Modify_Write) и происходит это так. Горят все светодиоды PORTB (все 8 штук), это значит, что на выводах PORTB установлена лог. 1. Решили погасить нулевой светодиод командой - PORTB.F0=0. В ходе выполнения этой команды контроллер сначала читает состояние на выводах PORTB (все 8) в аккумулятор, потом изменяет состояние нулевого бита в аккумуляторе на лог. 0 (при этом состояние других бит ему по фигу). И потом это измененное значение записывает в PORTB. При этом гарантированно только, что в нулевом бите будет 0, а на остальных будет то, что было считано с выводов (мы-то думаем что там были только лог. 1) , а считано там может быть что угодно (это зависит от характера нагрузки на выводах, помехи и т.д и т.п.). Вот и получается хотели погасить один светодиод, а погасли еще и другие (а может и нет). Вот такие вот грабли. Как обходить? Предлагаю такой вариант: Код:
unsigned short old_PORTB; // объявили переменную old_PORTB=0xff; // присвоили переменной нужное значение TRISB=0; // настроили на вывод PORTB=old_PORTB; // вывели в порт переменную old_PORTB.F0=0; // изменили бит в переменной PORTB=old_PORTB; // вывели в порт измененное значение |
01.04.2009, 08:13 | #42 |
Форумец
|
Еще один примерчик на светодиодах, к предыдущей схеме добавилась кнопка и резистор. Теперь в основном цикле ждем нажатия кнопки, и если она будет нажата, то будет загораться или гаснуть светодиод HL5, а в прерывании теперь будут моргать 4 светодиода ( HL1-HL4), только побыстрей.
Для обработки нажатия использовал встроенную в MikroC процедуру Button(). В железе проверено. Код:
unsigned short counter, oldstate, step; void interrupt(){ // подпрограмма обработки прерывания if(INTCON.T0IF){ counter++; if (counter>1){ PORTB=~PORTB&0x0f|step; counter=0; } INTCON.T0IF=0; } }// interrupt void Init(){ // подпрограмма начальной инициализации CMCON=7; // все входы как цифровые, компараторы отключены TRISA=0xff; // настроили выводы PORTA на вход TRISB=0; // настроили выводы PORTB на вывод OPTION_REG = 0x87; // настройка TMR0, прерывания будут каждые 66,304 ms INTCON.T0IE=1; // разрешили прерывания по переполнению TMR0 INTCON.GIE=1; // разрешили все прерывания step=0; oldstate=0; }// Init void main(){ Init(); while(1){ // организовали вечный цикл if (Button(&PORTA, 0, 1, 0)) oldstate = 1; if (oldstate && Button(&PORTA, 0, 1, 1)){ // ждем отпускания кнопки (переход от 0 к 1) step=~step&0x80; PORTB|=step; oldstate = 0; } } }//~ Если будут пожелания, то можно еще что-нибудь запустить. |
01.04.2009, 10:13 | #44 | ||
Форумец
|
Точного ответа на этот вопрос никто не даст. Это из разряда религиозных войн. А их лучше не начинать. С чего начинать все равно, сравнение придет со временем.
Цитата:
http://electronix.ru/forum/index.php - здесь есть AVR и PIC http://caxapa.ru/avr.html - здесь есть AVR и PIC. Про основной русский форум по AVR я не знаю. Цитата:
Последний раз редактировалось petrd; 01.04.2009 в 10:46. |
||
01.04.2009, 11:03 | #45 |
Форумец
|
Еще примерчик с ШИМ. Понятное дело, что яркость светодиода напряжением сильно не нарегулируешь. А вот при помощи ШИМ можно, а человеческий глаз свое дело сделает. Кнопкой на RA0 яркость светодиода можно увеличивать, а кнопкой на RA1 - уменьшать. Все достаточно просто. Схема ниже.
Код:
unsigned short j, old_j; void Init() { CMCON=7; // все входы цифровые, компараторы отключены PORTB = 0; // установили PORTB в 0 TRISB = 0; // настроили PORTB на выход PORTA = 0xff; // установили PORTA в 1 TRISA = 0xff; // настроили PORTA на вход Pwm_Init(5000); // настроили ШИМ модуль, период ШИМ - 5 кГц }// void main() { Init(); j = 80; // начальная инициализация j old_j = 0; // начальная инициализация old_j Pwm_Start(); // запуск ШИМ while (1) { // устроили бесконечный цикл if (Button(&PORTA, 0,1,0)) // нажимаем кнопку на RA0 j+=10 ; // увеличивается j (яркость больше) if (Button(&PORTA, 1,1,0)) // нажимаем кнопку на RA1 j-=10 ; // уменьшается j (яркость меньше) if (old_j != j) { // если было изменение j Pwm_Change_Duty(j); // то изменяем параметры ШИМ old_j = j; // и сохраняем новое значение } Delay_ms(200); // задержка 200 мсек } }//~ |
02.04.2009, 10:48 | #46 |
Форумец
|
Пример, как в MikroC можно работать с ЖКИ со встроенными контроллерами типа KS0066, HD44780. Инициализация ЖКИ на ассемблере обычно у начинающих вызывает затруднения. MikroC позволяет работать с 1, 2, 4-х строчными индикаторами. Здесь вся инициализация спрятана в процедуру Lcd_Config(), надо только правильно назначить порт и выводы контроллера и собственно все.
Код:
char *text = "mikroElektronika"; void main() { Lcd_Config(&PORTB, 4, 5, 6, 3, 2, 1, 0); // настройка подключения LCD LCD_Cmd(LCD_CLEAR); // Очистить дисплей LCD_Cmd(LCD_CURSOR_OFF); // Кусор выключен LCD_Out(1,1, text); // Вывести в первую строку слово "mikroElektronika" Delay_ms(1000); // задержка в 1 сек LCD_Out(2,6,"mikroE"); // Вывести во вторую строку, начиная с 6-й позиции слово "mikroE" } Код:
sbit LCD_RS at RB4_bit; sbit LCD_EN at RB5_bit; sbit LCD_D4 at RB0_bit; sbit LCD_D5 at RB1_bit; sbit LCD_D6 at RB2_bit; sbit LCD_D7 at RB3_bit; sbit LCD_RS_Direction at TRISB4_bit; sbit LCD_EN_Direction at TRISB5_bit; sbit LCD_D4_Direction at TRISB0_bit; sbit LCD_D5_Direction at TRISB1_bit; sbit LCD_D6_Direction at TRISB2_bit; sbit LCD_D7_Direction at TRISB3_bit; char *text = "mikroElektronika"; void main() { LCD_Cmd(_LCD_CLEAR); // Очистить дисплей LCD_Cmd(_LCD_CURSOR_OFF); // Кусор выключен LCD_Out(1,1, text); // Вывести в первую строку слово "mikroElektronika" Delay_ms(1000); // задержка в 1 сек LCD_Out(2,6,"mikroE"); // Вывести во вторую строку, начиная с 6-й позиции слово "mikroE" } Последний раз редактировалось petrd; 12.09.2012 в 20:32. |
02.04.2009, 13:16 | #47 |
Форумец
|
Вот на kazus.ru увидел - продают самодельные программаторы http://kazus.ru/url.php?url=http://mkpochtoi.narod.ru/
|
03.04.2009, 12:08 | #48 |
Форумец
|
А вот и термометр. В качестве датчика использован цифровой датчик температуры DS18B20, выдающий данные по шине 1-Wire. Температура измеряется с шагом 0,0625 градуса, точность измерения составляет +0,5 градуса. В программе использована встроенная в MikroC библиотека для работы с устройствами по шине 1-Wire. Вывод на отображение температуры два раза в секунду.
Код:
const unsigned short TEMP_RESOLUTION = 12; char *text = "000.0000"; unsigned temp; void Display_Temperature(unsigned int temp2write) { const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8; char temp_whole; unsigned int temp_fraction; // преобразование отрицательной температуры if (temp2write & 0x8000) { text[0] = '-'; temp2write = ~temp2write + 1; } // извлечение целой части temp_whole = temp2write >> RES_SHIFT ; // преобразование целой части температуры в символы text[0] = temp_whole/100 + 48; text[1] = (temp_whole/10)%10 + 48; // извлечение десятков text[2] = temp_whole%10 + 48; // извлечение единиц // извлечение и преобразование дробной части temp_fraction = temp2write << (4-RES_SHIFT); temp_fraction &= 0x000F; temp_fraction *= 625; // преобразование дробной части в символы text[4] = temp_fraction/1000 + 48; text[5] = (temp_fraction/100)%10 + 48; text[6] = (temp_fraction/10)%10 + 48; text[7] = temp_fraction%10 + 48; // вывод температуры на ЖКИ Lcd_Out(2, 5, text); }//~ void main() { CMCON = 7; // Все входы цифровые TRISA=0xff; Lcd_Config(&PORTB, 4, 5, 6, 3, 2, 1, 0); // назначение выводов ЖКИ - PIC Lcd_Cmd(LCD_CURSOR_OFF); Lcd_Out(1, 1, " Temperature: "); // вывод символа точки и "С" как единицы измерения Lcd_Chr(2,13,223); Lcd_Chr(2,14,'C'); //--- главный цикл do { //--- чтение температуры из DS18B20 Ow_Reset(&PORTA,2); // сигнал сброса Ow_Write(&PORTA,2,0xCC); // команда SKIP_ROM Ow_Write(&PORTA,2,0x44); // команда CONVERT_T Delay_us(120); Ow_Reset(&PORTA,2); Ow_Write(&PORTA,2,0xCC); // команда SKIP_ROM Ow_Write(&PORTA,2,0xBE); // команда READ_SCRATCHPAD temp = Ow_Read(&PORTA,2); temp = (Ow_Read(&PORTA,2) << 8) + temp; //--- форматирование и вывод температуры Display_Temperature(temp); Delay_ms(500); } while (1); } Последний раз редактировалось petrd; 28.04.2009 в 15:45. |
04.04.2009, 10:43 | #50 |
Форумец
Сообщений: 552
Регистрация: 17.06.2005
Возраст: 40
Не в сети |
Начинание конечно хорошее, но чем оно отличается от любого самоучителя в нете???
Так ребятки нажмите кнопочку ПУСК ... опа появилась менюшка. Все видите? Ай да молодцы! Теперь нажмите Программы, далее Microcoft Word, в результате чего у нас появилось окошечко Ворда. Теперь закроем его, нажав на кнопочку крестик в вверхнем правом углу. Все нажали??? Ай да молодцы! Поздравляю теперь Вы дипломированные программисты. Дипломы заберете на выходе. З.Ы. Учится нада с основ( цифровая схемотехника( логика), покодить на компе, а уж потом на мелкашки переходить). А иначе дальше "кнопки ПУСК" никак. |
04.04.2009, 11:51 | #51 |
Registered User
Сообщений: 391
Регистрация: 16.11.2008
Не в сети |
тему поддерживаю. Конечно нужно начинать с основ и даже я не успеваю за petrd, я даже еще не прикупил PICkit2, но спасибо за http://kazus.ru/url.php?url=http://mkpochtoi.narod.ru/ письмо написал, но есть сомнения на счет гарантий сделки... Ну эт ладно, теперь по теме: есть задумка собрать терморегулятор в диаппазоне где-то 60 град до 110 и наверно на МК...
Так что, вопросы будут, но позже и надеюсь на помощь как автора так и остальных форумцев. Спасибо. |
04.04.2009, 13:13 | #53 | |
Форумец
|
Цитата:
1. Я хотел показать, что путь от "ХОЧУ, НО НЕЗНАЮ С ЧЕГО НАЧТЬ" до "И ПРАВДА РАБОТАЕТ" при наличии подсказок очень быстрый. 2. Отличие от учебников в нете - учебника по MikroC в нете не видел, хотя в нем самом HELP как учебник (большинство учебников идет по академическому пути - обычно долго и на ассемблере), я готов ответить на возникающие вопросы по языку и контроллеру в кратчайшее время. А главное отличие - мои посты не учебник, а Quick Start. Быстро стартанул - понравилось, буду разбираться дальше, не понравилось - выбросил и забыл. 3. Про тупое нажатие кнопок. 1-3 раз тупое, 4-10 раз обдуманно. 11-й и дальше на автомате, сосредоточившись на написании программы. 4. Кто пришел к микроконтроллерам сам (а не после пинка преподавателей ВУЗа), те знают, что такое цифровая техника и объяснять им это не надо. 5. Программировать начинать обязательно на ПК? Почему? Пусть это будет С++, так его основа это Си, а MikroC основан как раз на ANSI Си (стандарт языка Си). Начав программирование на языке ООП с нуля сразу сталкиваешся с трудностью понимания объектов, классов. А в классическом Си этого всего нет, а для МК и не надо. Так что сначала Си, а потом С++ и т.д. От простого к сложному. |
|
04.04.2009, 21:28 | #55 |
Форумец
|
Буратино тоже можно ножиком выстругать, а можно лобзиком выпилить и не париться. Абсолютно ничего не имею против ассемблера, но два последних примера, что я приводил, написанные на ассемблере, могут напугать начинающего до заикания. А писать в машинных кодах в наши дни - это, по-моему, лучшее средство для самоистязания. Если есть инструмент, то уровень ПРОСТОГО переходит на качественно новый и более высокий уровень. Или не так?
|
04.04.2009, 22:45 | #56 | |
Инженер
|
Цитата:
Думаю, функцию, которая из полученных с датчика по SSI интерфесу 32 бит "выдерет" 25 бит кода, "расчленит" его на количество оборотов и текущую позицию, а так же умножит на постоянный коэффициент для получения миллиметров - лучше писать на ассемблероподобном языке(опять же - в моём случае её на чём-то другом не напишешь). А вот вызов таких функций для пары датчиков раз в 100 мс, вычисление перекоса и позиций - уже на чём-то си- либо паскале-подобном. P.S. Всё упрощено, кто разбирается в симатиках - не придирайтесь P.P.S. Продолжайте про микроконтроллеры - интересно ведь! |
|
04.04.2009, 23:03 | #57 | |
Форумец
Сообщений: 552
Регистрация: 17.06.2005
Возраст: 40
Не в сети |
Цитата:
Стоит ли начинать свою "жизнь" со "сказок", ведь потом придется достаточно круто обламываться ??? P.S.XPEH_BAM, Не пора ли тему почистить от всяких рассуждений и чьих то личных достижений -------------------------------------------------------------------------------------------------------------------------------- Эт как это без "попинать" немнога ?!?!?! Традиции нарушать нельзя Последний раз редактировалось dr.ON; 04.04.2009 в 23:45. |
|
05.04.2009, 09:21 | #58 |
Форумец
|
|
05.04.2009, 17:06 | #60 |
Форумец
|
Конечно сойдет. ChipProg2 - чистый универсальный программатор, без возможности отладки. Но и PICKit2 из среды MikroC тоже не умеет отлаживать, так что для нашего случая преимуществ никаких не дает ни тот ни другой. Так что можно уже и железо щупать, если PIC какой-нибудь есть.
|