Если это ваш первый визит, рекомендуем почитать справку по форуму. Для размещения своих сообщений необходимо зарегистрироваться. Для просмотра сообщений выберите раздел. |
PIC контроллеры. Программаторы и первый проект на PIC |
Программирование микроконтролеров,ремонт аудио/видео/бытовой техники,полезные устройства для дома,телефония, обсуждение статей журнала Радио |
|
Опции темы |
20.07.2018, 10:41 | #1231 | |
Форумец
|
Цитата:
|
|
05.02.2019, 21:46 | #1232 |
Форумец
Сообщений: 4
Регистрация: 26.01.2012
Возраст: 54
Не в сети |
Здравствуйте. Изготовил кабелеискатель. http://vrtp.ru/index.php?showtopic=13470&st=90 Передатчик собран по представленной схеме. Частота на выходе 125 кГц с АМ модуляцией 1 Гц. Использую кварц 16 МГц, контроллер PIC12f675.
Появилась хотелка иметь на выходе двухтональный сигнал. 125 кГц скажем 4 раза в секунду поочередно модулируется 1 кГц затем 2 кГц и т. д. Короче хочу чтоб было в линии «ти-ли-ти-ли-ти… » . Решил переписать прошивку самостоятельно в среде mikroC PRO for PIC используя прерывание Timer0. По прерыванию инвертирую сигнал на ножке . Предделитель таймера рассчитал калькулятором PICTimerCalculator. По расчетам, на 6 ноге должно быть 125 кГц (несущая) а частотомер (в железе) показывает не более 16 кГц. В программе модуляцию не использую, пока не разберусь с несущей. С контролером имею дело впервые. Пытаюсь разобраться, но чувствую, что самостоятельно не справлюсь. Может контроллеру просто не хватает скорости? Прошу вашей помощи. Код:
/* pic12F675 внешний кварц 16 Мгц выход 6 нога GP1 генерация 1кгц и 2 кгц меняется с частотой 4 гц. несущая 125 кгц. 1000гц = 125000/125 2500гц = 125000/50 5гц = 125000/25000 //Timer0 //Prescaler 1:1; TMR0 Preload = 240; Actual Interrupt Time : 4 us */ unsigned int T5; // переменная счетчик для 4 Гц 0 .. 65535 bit kvant, Maska, F5; //переменная void InitTimer0(){ CMCON = 0x07; // Disable Comparator ADCON0 = 0x00; // Disable ADC ANSEL = 0x00; // All ports in digital TRISIO = 0x00; // All pins in OUT GPIO = 0; // на выводах gp 0 //OPTION_REG = 0xA8; // Assign prescaler to TMR0 //Timer0 Registers: //Prescaler=1:1; TMR0 Preset=240; Freq=125*000,00Hz; Period = 4 ns WPU = 0x00; //Выключение подтягивающих резисторов OPTION_REG.NOT_GPPU = 1; // bit 7 Запретить использование подтягивающих резисторов 1, разрешить 0. OPTION_REG.INTEDG = 0; // bit 6 Выбор фронта импульса на входе внешнего прерывания. OPTION_REG.T0CS = 0; // bit 5 выбор тактового сигнала 1 внешний gp2 0 внутренний генератор или кварц. OPTION_REG.T0SE = 0; // bit 4 TMR0 выбор фронта приращения при внешнем тактовом сигнале bit: 0=low/high / 1=high/low OPTION_REG.PSA = 0; // bit 3 выбор включения предделителя bit: 1 перед WDT, 0 перед Tmr0 OPTION_REG.PS2 = 0; // bits 2-0 PS2:PS0: Prescaler Rate Select bits OPTION_REG.PS1 = 0; OPTION_REG.PS0 = 0; TMR0 = 240; //240 устанавливаем начальное значение Timer0 250 кГц // один период два переключения порта //INTCON = 0xA0; // Enable TMRO interrupt INTCON.T0IE=1; // разрешили прерывания по переполнению TMR0 INTCON.GIE=1; // включили механизм прерываний kvant = 0; // переменная генератор 125 кГц ее выводим на 6 ногу Maska = 0; //переменная состояние выхода модуляция частотами F5 = 0; //переменная переключатель частоты 1кГц 2кГц T5 = 0; //переменная счетчик для 4 Гц } void Interrupt(){ if (INTCON.T0IF){ // флаг прерывания переполнения Timer0 поднялся kvant = ~kvant; // инвертируем состояние переменной после прерывания //kvant = kvant&Maska; // применим маску разрешающую изменять состояние для выхода(логическое И) GPIO.B1 = kvant; // Выводим сигнал на 6 ногу //T5++; // increment T5 //if (T5 > 25000){ // задержка для 4 Гц // T5 = 0; // F5 = ~F5; // Инвертируем флаг изменения частоты 1кГц 2кГц // } INTCON.T0IF = 0; // сбрасываем флаг прерывания Timer0 INTCON.T0IE = 1; // разрешили прерывания по переполнению TMR0 TMR0 = TMR0 + 240; // устанавливаем начальное значение Timer0 } } void main() { InitTimer0(); do{ // if (F5) { //Delay_us(500); //} //else{ //Delay_ms(1); //} //Maska = ~Maska; } while(1); } |
06.02.2019, 09:36 | #1235 |
Форумец
|
Возможно. Уберите все из прерывания до минимума, добейтесь какой-то частоты на выходе которая совпадает с расчетами и измерениями и начните ее повышать, посмотрите когда перестанет расти. А потом добавляйте код в прерывание и тоже смотрите. Все будет понятно.
|
07.02.2019, 19:47 | #1239 |
Следопыт
Сообщений: 947
Регистрация: 25.11.2009
Не в сети |
petrd, предполагаю что загвоздка в описании прерывания. Я написал бы так: после наступления прерывания таймер остановить, прерывания запретить, сброс флага и обнуление счётчика таймера, требуемая процедура, запись нужного значения в счётчик, пуск таймера, разрешение прерываний. На мой взгляд предоставленном коде происходит следующее: при возникновении прерывания и его выполнения счётчик таймера продолжает считать. В момент установки начального значения происходит суммирование значения в регистре с заданным числом. Соответственно следующее прерывание наступит раньше и погрешность эта растёт с каждым циклом. На крайняк добавить строку в программу, обнуляющую счётчик таймера. Что думаете?
|
07.02.2019, 23:16 | #1240 |
Форумец
Сообщений: 4
Регистрация: 26.01.2012
Возраст: 54
Не в сети |
Ребята, спасибо за поддержку. Походу сам запутался и вас начал путать.
Естественно я пробовал разные варианты конфигурации с делителем и проверял в железе. Но всегда писал так Код:
OPTION_REG.PSA = 1; // bit 3 выбор включения предделителя bit: 1 перед WDT, 0 перед Tmr0 На форум по ошибке выложил последнюю версию, где Код:
OPTION_REG.PSA = 0; Спросите почему ставил 1? Потому что учился, повторял по примеру (с ошибкой) https://alex-exe.ru/radio/microcontrollers/timer-pic/ |
18.02.2019, 21:39 | #1241 |
Форумец
Сообщений: 4
Регистрация: 26.01.2012
Возраст: 54
Не в сети |
«Слабенький» этот контроллер для таких частот, но я получил, что хотел. Может, кому пригодится. Короче, сделал наоборот. В основном цикле формирую несущую, а в прерывании управляю модуляцией сигнала. Кварц заменен на 20Мгц.
Код:
/* pic12F675 pic12F629 внешний кварц 20 Мгц выход 6 нога GP1 генерация приблизительно 1кгц и 2 кгц меняется с частотой 4 гц. несущая 125 кгц. */ unsigned int T5; // переменная счетчик для 4 Гц 0 .. 65535 bit kvant, Maska, F5; //переменная void InitTimer0(){ CMCON = 0x07; // Disable Comparator //ADCON0 = 0x00; // Disable ADC //ANSEL = 0x00; // All ports in digital TRISIO = 0x00; // All pins in OUT GPIO = 0; // на выводах gp 0 WPU = 0x00; //Выключение подтягивающих резисторов OPTION_REG.NOT_GPPU = 1; // bit 7 Запретить использование подтягивающих резисторов 1, разрешить 0. OPTION_REG.INTEDG = 0; // bit 6 Выбор фронта импульса на входе внешнего прерывания. OPTION_REG.T0CS = 0; // bit 5 выбор тактового сигнала 1 внешний gp2 0 внутренний генератор или кварц. OPTION_REG.T0SE = 0; // bit 4 TMR0 выбор фронта приращения при внешнем тактовом сигнале bit: 0=low/high / 1=high/low OPTION_REG.PSA = 0; // bit 3 выбор включения предделителя bit: 1 перед WDT, 0 перед Tmr0 OPTION_REG.PS2 = 0; // bits 2-0 PS2:PS0: Prescaler Rate Select bits OPTION_REG.PS1 = 0; OPTION_REG.PS0 = 1; TMR0 = 1; // устанавливаем начальное значение Timer0 INTCON.T0IE = 1; // разрешили прерывания по переполнению TMR0 INTCON.GIE = 1; // включили механизм прерываний kvant = 0; // переменная генератор 125 кГц ее выводим на 6 ногу F5 = 0; //переменная переключатель частоты 1кГц 2кГц T5 = 0; //переменная счетчик для 4 Гц Maska = 1; //переменная состояние выхода модуляция частотами } void Interrupt(){ if (INTCON.T0IF){ // флаг прерывания переполнения Timer0 поднялся TMR0 = 1; // устанавливаем начальное значение Timer0 T5++; // increment T5 if (T5 > 1000){ // задержка для ~4 Гц T5 = 0; F5 = ~F5; // Инвертируем флаг изменения частоты ~1кГц ~2кГц } if (F5) { OPTION_REG = 0x10000001; } else{ OPTION_REG = 0x10000010;; } Maska = ~Maska; INTCON.T0IF = 0; // сбрасываем флаг прерывания Timer0 } } void main() { InitTimer0(); do{ asm { nop // подобрал 125 кгц, без вставки nop 178,5 кгц nop nop nop nop nop } kvant = ~kvant; // инвертируем состояние переменной kvant = kvant&Maska; // маской модулируем несущую(логическое И) GPIO.B1 = kvant; // Выводим сигнал на 6 ногу } while(1); } |
18.09.2020, 07:16 | #1242 |
Форумец
Сообщений: 17
Регистрация: 19.02.2017
Возраст: 59
Не в сети |
Пётр, привет. Есть такая непонятка, третий день ничего не получается. Есть два контакта, при замыкании первого сигнала нет, а при замыкании обоих или размыкании сигнал должен быть, но работает только при разомкнутых и замкнутом первом. Как написать, чтобы оба вместе замкнутые давали сигнал? У меня никак. И так делал,
Код:
#define On1 Button(&gpio,5,10,0) #define On2 Button(&gpio,4,10,0) void On(){ gpio.f1=1; } void Off(){ gpio.f1=0; } void init(){ cmcon=7; trisio=0x38; gpio=0; } void main(){ init(); if(On1){ Off(); } else{ if(On1){ if(On2){ On(); } else{ On(); } } } } Код:
void main(){ init(); if(On1){ Off(); } else{ if((On1)&&(On2)){ On(); } else{ On(); } } } |
18.09.2020, 10:59 | #1244 |
Форумец
Сообщений: 17
Регистрация: 19.02.2017
Возраст: 59
Не в сети |
12f629, что цикла нет я заметил уже поздно, но, что интересно, при разомкнутых сигнал есть, при замыкании первого пропадает, и обратно. Может из-за этого и не заметил, что цикла нет. Добавлю, посмотрю, что получится. А всё-таки, какая запись более правильная?
|
18.09.2020, 11:29 | #1245 |
Форумец
|
Без цикла программа исполнится один раз и остановится. А из Ваших слов понятно, что что-то и потом происходит, отсюда возникает неоднозначность в оценке происходящего. И поэтому ответов у меня пока нет. Возможно строжевик срабатывает. Сначала сделайте цикл и покажите настройки битов конфигурации, а там посмотрим.
|
20.09.2020, 08:19 | #1249 |
Форумец
|
|
21.09.2020, 16:40 | #1257 |
Форумец
|
А у меня работает, правда контроллер 628A, но код тот же
Попробуйте Код:
#define On1 GPIO5_bit #define On2 GPIO4_bit Код:
#define On1 Button(&GPIO,5,10,0) #define On2 Button(&GPIO,4,10,0) 1 2 Выход 0 0 1 0 1 0 1 0 0 1 1 1 На выходе у меня светодиод. Последний раз редактировалось petrd; 21.09.2020 в 16:57. |
29.09.2020, 13:31 | #1258 |
Форумец
Сообщений: 17
Регистрация: 19.02.2017
Возраст: 59
Не в сети |
Попробовал, получил кучу ошибок, самая первая "необъявленный идентификатор в выражении" там, где в main() первое обращение к On1 (if (On1){) всего 9 ошибок.
|
09.10.2020, 15:09 | #1260 |
Форумец
Сообщений: 17
Регистрация: 19.02.2017
Возраст: 59
Не в сети |
Пётр, привет. Да, у меня такой вариант работает, но дело в том, что нужны чёткие 3 состояния: разомкнуты оба контакта-включено, замкнут 1-й контакт-выключено, замкнуты оба контакта-включено. Просто я пошёл по простому пути - сначала добиться правильной работы светодиода, а потом дописать необходимое.
|