-
Постов
219 -
Зарегистрирован
-
Посещение
Тип контента
Профили
Форумы
Блоги
Сообщения, опубликованные Zombie47
-
-
Так и что мне с этой информацией делать не понимаю
0 -
-
5 часов назад, IMXO сказал:
напряжение вы получите , вне зависимости от наличия/отсутствия кондерчиков , другое дело что выход ЦАП высокоомный и требует наличия повторителя для дальнейшего использования
Например я это напряжение буду замерять мультиметром что в таком случае будет? оно просядет? насколько?
Цитатаа накой это нужно? сразу использовать сигнал с усилителя термопары религия не позволяет?
не религия а скорее знания не позволяют )
вообще сигнал с термопары у меня идет на MAX6675 и им обрабатывается считывается МК и выводиться на дисплей и еще планирую делать выход с МК чтобы заслать эту инфу в мозг ДВС0 -
Помогите разобраться с модулем ЦАП на PIC16f1847.
Вот я смотрю 5 страницу даташита и вижу там что вроде как модуль DAC доступен только на ноге RA2.
Дальше еще будут вопросы про конфигурацию и тд.
Я хочу получить на выходе вольтаж от 0 до 5 вольт. Вольтаж будет зависеть от переменной. Переменная это будет температура которая получается с термопары. от 0 до 1024
соответственно при 512 температуре у меня должно быть 2.5вольта
Дискретность сигнала (то-есть как быстро будет меняться вольтаж на выходе) она же температура. От 0.5 до 1 сек.
Я могу просто получать напряжение с ноги и все? или же надо повесить на выход ноги какие нить резисторы кондерчики и тд?
0 -
Цитата
Да тут дело в машине. МАшина Subaru. На моделях после 2004 года на коробке передач нет датчика скорости.
нагуглил эту тему поиском по гуглу "сигнал с датчика абс на микроконтроллер"
читаю субару =)))) как раз таже ситуация =))) Сейчас думаю как грамотно это реализовать.0 -
Неважно, получите вы в переменных a и b 10 и 96 или 0х0A и0х60 - это одно и тоже!!
Я тоже так думал и сделал программу которая отправила пакет в кан шину.
отправила пакет 96 10 (перевернутый 10 96) и блок который принимает пакет так как он принимает в хексе перевел эти десятичные числа еще раз в десятичные! так как он думает что это все в хексе пришло. тоесть для принимающего блока пришло 96 и 10 в шестнадцатиричной,
0 -
КЕС сдается мне Зомби сам не понимает что ему надо и зачем в результате непонимания разницы между двоичной и двоично-десятичной системой исчисления.... и пользование ваших формул или сдвига ему не помогут
да все верно только щас пришел к пониманию =) вообщем мне нужно отправить пакет с переменными a и b
в переменной a должно быть к примеру 0A
а в переменной b должно быть к примеру 60
тоесть speed равно 1096 и это число нужно разбить на 10 и 96 и перевести в hex
Вопрос, каким образом мне в СИ из числа 1096 получить две переменные со значениями 0A и 60 ?
0 -
Да как я понял это опять проблемы протеуса. на реальной плате все работает.
0 -
Блин с элементарной вещью разобраться не могу, че у меня порты не горят а моргают?
PIC16F819
Уже всю программу закомментил и осталось вот что:
void init(void) { INTCON =0b00000000; PORTA = 0; //îáíóëÿåì ïîðòû à PORTB = 0; TRISA = 0b00000000; //âñå ïîðòû RA íà âûõîä TRISB = 0b00000000; void main(){ init(); //âûçûâàåòñÿ ôóíêöèÿ init while(1) { RA0_bit=1; RA1_bit=1; RA2_bit=1; RA3_bit=1; RA4_bit=1; RA6_bit=1; RA7_bit=1; RB0_bit=1; RB1_bit=1; RB2_bit=1; RB3_bit=1; RB4_bit=1; RB5_bit=1; RB6_bit=1; RB7_bit=1; } }
Порты RA0-RA3 моргают а не горят
где я накосячил?
Среда microC и кстати как кодировку нормальную поставить чтобы копировались комментарии?
0 -
Лучше полностью вопрос задам, а не по частям =)
Как мне грамотно записать вот это уравнение чтобы оно быстро считалось в МК и грамотно его разделить на два байта
speed=((imp*0.3864/0.1)*3.6)/0.05625;
к примеру imp=14 тогда результат будет 3462 и в две переменные записать 34 и 62
0 -
Как использовать побитовый сдвиг? К примеру у меня число 1066 в десятичной или оно же в 16ричной - 42A, или же оно же в двоичной 10000101010
в двоичной мне надо отделить 1000010 от 1010
тоесть по сути надо сдвинуть на 8 бит, но какое число я получу если сделаю сдвиг на 8 бит первое или второе?
0 -
Подскажите получаю переменную равную например 60, мне нужно поделить её на 0.05625, то-есть получиться 1066 и это число перевести в HEX получиться 42A а дальше нужно разбить это число и записать в две переменные
переменная1 = 42
переменная2 = A0
Как мне из 60 оптимально получить две переменные?
Язык СИ
МК PIC16F819
Компилятор microC
0 -
Да не я аж с комментариями код разбирал http://pro-diod.ru/article/mcp2515-can-kontroller.html
Хотя вот щас поглядел еще раз и как понимаю создана функция которая вызывает функцию по SPI и по сути по SPI Шлет инфу конфигурации в MCP, я правильно понял?
Ну вот к примеру
mcp_write(CANINTE,0x00);
тоесть конфигурация MCP осуществляется записью в определенные регистры данных по SPI
0 -
Позже вернусь к выше написанному а пока что следующий вопрос по пику.
мне нужно слать по кан шине пакет с данными.
Планирую сооружать вот по такой схеме:
Есть пару вопросов, во-первых обязательно ли нужен кварцевый резонатор на 8Mhz для MCP2510?
Как я понимаю мне надо сконфигурировать МК и сконфигурировать MCP2510, я примеры программ видел но не очень понял. Понимаю что МК общается с MCP2510 по SPI, тоесть я пишу программу для МК и в ней пишу конфигурацию для MCP2510 и шлю эти конфигурационные данные по SPI? Если да то почему я не нашел этого места в коде? Или я чего то не понимаю?
0 -
Еще раз. Не обижайтесь. Написана полная чушь. Исправлять бессмысленно.
А я и не обижаюсь, все что у меня написано в коде это все по советам в этой ветке =) Так что нужно обижаться им.
А я изначально все спрашивал как грамотно и тд и тп.
Буду пробывать по вашему варианту. вчитываться и вдумываться.
0 -
-
Вот, в программе convert, если tm>999,
ТЬФУ ТЫ БЛИН=)))))))))
0 -
Бит PEIE в регистре INTCON выключен, значит прерывания от ССР не пройдут.
А блин точно забыл посмотреть прерывания =)) PEIE не нужен же для TMR0 поэтому и вырублен был в предыдущей проге.
Ну и CCP1IE соответственно тоже забыл что надо врубить.
ыводите на индикатор period, а то current_timer всё время будет изменяться и мелькать на индикаторе.Вообще туда будет выводиться функция
Speed (tm)
Все включил но все ровно если вывожу period То просто ноль выводит
У Вас значение периода в микросекундах, величина периода будет единицы-десятки тысяч. На трёх разрядах индикатора увидите только последние 3 цифры, они могут болтаться от нестабильности генератора, например.Значение периода да у меня в микросекундах, подаю 19,5 мсек тоесть 19500 микросек, тоесть я должен увидеть хотя бы 500, а я вижу 0
0 -
Ок, я просто весь код программы стесняюсь выкладывать чтобы не засорять ветку.
/* * File: newmain.c * Author: Vlad * * Created on 16 ???????? 2015 ?., 0:37 /* 7bit=0 () 6bit=0 () 5bit=0 () 4bit=0 () 3bit=0 () 2bit=0 () 1bit=0 () 0bit=0 () */ #pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTRC oscillator; port I/O function on both RA6/OSC2/CLKO pin and RA7/OSC1/CLKI pin) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled) #pragma config MCLRE = OFF // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital I/O, MCLR internally tied to VDD) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Low-Voltage Programming Enable bit (RB3/PGM pin has digital I/O function, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EE Memory Code Protection bit (Code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off) #pragma config CCPMX = RB2 // CCP1 Pin Selection bit (CCP1 function on RB2) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) #include <xc.h> #include <pic.h> #include <pic16f819.h> #include <stdlib.h> #define dig1 RA3 //индикатор 1 #define dig2 RA2 //индикатор 2 #define dig3 RA7 //индикатор 3 #define LED PORTB // глобальные переменные volatile unsigned int period; long old_timer; long current_timer; long speed; const unsigned char digits [23] = {0x44,0x7D,0x16,0x15,0x2D,0x85,0x84,0x5D,0x04,0x05,0xFF,0x86,0x0C,0x40,0x79,0x12,0x11,0x29,0x81,0x80,0x59,0x00,0x01}; //0,1,2,3,4,5,6,7,8,9,пусто, E,R, - // это коды которые сообщают какие светодиоды поджечь в индикаторе чтобы отобразить ту или иную цифру или символ. Код зависит от того какая нога к какому выводу МК подрублена. в инете есть калькуляторы. unsigned int i ; // volatile unsigned char a,b ;//volatile это спецификатор говорит компилятору, что это переменная, чтобы он ее не оптимизировал, Отдельная плюшка) volatile unsigned char LEDS[3] ; // //*********************************************************************** //* ИНИЦИАЛИЗАЦИЯ МК //*********************************************************************** void init(void) { INTCON =0b00000000; // даташит page 18 ниже описание: //7bit=0 (GIE глобальное разрешение прерываний выкл) //6bit=0 (PEIE разрешение прерываний от периферийных модулей выкл) //5bit=0 (TMR0IE разрешение прерывания по переполнению таймера TMR0 выкл) //4bit=0 (INTE разрешение внешних прерываний выкл) //3bit=0 (RBIE разрешение прерывания по изменению сигнала на входах RB4-RB7) //2bit=0 (TMR0IF флаг прерывания который поднимается при переполнении таймера, мы его сбрасываем в 0) //1bit=0 (INTF флаг прерывания который поднимается если выполнено условие внешнего прерывания на выводе RB0/INT, мы его сбрасываем в 0) //0bit=0 (RBIF флаг прерывания который поднимается при измении сигнала на одном из входов RB4-RB7, мы его сбрасываем в 0 ) OSCCON = 0b01100100; //даташит page 38 ниже описание: //7bit=0 (READ as 0) //6-4bit=110 (частота внутреннего генератора 4mhz) //3bit=0 (READ as 0) //2bit=1 (IOFS стабилизация частоты INTOSC вкл ) //1-0bit=0 (READ as 0) // ниже настройка портов PORTA = 0; //обнуляем порты а PORTB = 0; TRISA = 0b01110001; //порты RA2, RA3, RA7, RA1 на выход а остальные на вход TRISB = 0b00000100; // RB2 на вход для модуля захвата CCP PORTA = 0; //обнуляем порты а PORTB = 0; // ниже настройка АЦП ADCON0=0b01000000; //даташит page 81 ниже описание: //7-6bit=01 (Если ADCS2=0 то задается частота Fosc/8) //5-3bit=000 (канал для АЦП RA0) //2bit=0 (GO/DONE как я понял это что вроде флага, в процессе АЦП или нет ) //1bit=0 (READ as 0) //0bit=1 (ADON этот бит запускает работу ацп.) // ниже настройка таймера TMR0 TMR0 = 0; //сбрасываем таймер в 0 TMR1 = 0; OPTION_REG = 0b00000011; //ниже описание (даташит page 54): //7bit=0 (portb подтягивающие резисторы вкл) //6bit=0 (INTEDG прерывания по заднему фронту сигнала) //5bit=0 (источник тактирования таймера 0 = внутренний генератор) //4bit=0 (в какую сторону считает таймер, от меньшего к большему) //3bit=0 (прескалер применяется к Timer0 а не к WDT) //2-0bit=011 (прескайлер равен 1:16) //Ниже настраиваем модуль захвата CCP1CON = 0b00000101; /* 7-6bit=0 (Read as 0) 5bit=0 (Младшие биты скважности. В режиме захвата не используются) 4bit=0 (Младшие биты скважности. В режиме захвата не используются) 3-0bit=0101 (0101 - Захват по каждому переднему фронту сигнала) */ //Ниже настраиваем Таймер1 для модуля захвата, работают в паре. T1CON = 0b00000001; /* 7-6bit=0 (Read as 0) 5-4bit=00 (Предделитель для TMR1 1:1) 3bit=0 (T1OSCEN Внутренний генератор выкл 0 (еслди вкл то не будут работать RB6, RB7) 2bit=0 (Синхронизация внешнего тактового сигнала Если TMR1CS=0 то значение бита игнорируется) 1bit=0 (TMR1CS выбор источника тактового сигнала. 0 - внутренний генератор) 0bit=1 (TMR1ON 1 таймер включен) */ // ниже разрешение прерываний TMR0IE = 1; //разрешение прерывания по таймеру0 GIE = 1; // глобальное разрешение прерываний }; void interrupt Timer (void) { if (CCP1IF){//произошло прерывание по входному сигналу на RB2 с датчика скорости, по переднему фронту current_timer = CCPR1L+(CCPR1H<<8);//время между двумя импульсами period = (current_timer - old_timer); old_timer = current_timer; CCP1IF = 0; } if (TMR1IF){//если таймер TMR1 переполнился TMR1IF = 0; } if(TMR0IF) // таймер считает до такого числа которое мы указали в настройках таймера " OPTION_REG = 0b00000011; // настройки таймера 1:16 и установка Set timer TMR0 даташит page 54" и когда он досчитает он поднимает флаг, мол я досчитал! флаг TMR0IF если он равен 1 значит он поднят и выполняется тело ниже { TMR0IF=0; //сбрасывается этот же флаг чтобы он начал считать заново. dig1=0; NOP(); dig2=0;NOP(); dig3=0; LED=(digits [10]); // гасим все разряды b++; //увеличиваем b на 1. изначально она равна нулю. if (b>130){b=0;} //если b уже равна больше 130 то обнуляем её. Это как бы второй счетчик, параллельный основному. a++; //тоже что и b но счетчик для индикации switch(a) //выбор вариантов в зависимости от значения а. В первый раз а будет равно 1 и поэтому будет работать case 1 { // Динамическая индикация. case 1: LED=(LEDS[2]); dig1=0; NOP(); dig2=0; NOP(); dig3=1; break; // сначала отправляем цифру LEDS[2] а потом поджигаем первый разряд dig3=1 чтобы увидеть эту цифру case 2: LED=(LEDS[1]); dig1=0; NOP(); dig3=0; NOP(); dig2=1; break; // второй разряд case 3: LED=(LEDS[0]); dig2=0; NOP(); dig3=0; NOP(); dig1=1; a=0; break; // третий разряд и вконце обнуляем a и счетчик теперь опять будет считать с 0 } } } int Speed (int tm){ //функция формула расчета скорости tm = (2.032/((period/1000000)*5))*3.6; } void convert (void)//функция которая переводит значения температуры в графические показания на 3 разрядном семисегментном индикаторе { unsigned int d1_1; // int tm; unsigned char tempLEDS[3] ; // масив в который будем заносить значения из другого массива (не числа) tm = current_timer; //вывод на индикатор данного числа if(tm>=0 && tm<10){ //если tm больше 0 но меньше 10 то выполняем тело tempLEDS[2]=digits [10]; //посылаем пустой знак NOP(); tempLEDS[1]=digits [10]; //посылаем пустой знак NOP(); tempLEDS[0]=digits [tm]; //посылаем знак равный tm } if (tm >= 10 && tm <= 99){ tempLEDS[2]=digits [10]; // если значение от 10 до 99 то на 1 индикатор подаем цифру пусто. NOP(); d1_1=tm%100; tempLEDS[1]=digits [d1_1/10]; // Получаем разряд tempLEDS[0]=digits [d1_1%10]; // Получаем разряд } if (tm >=100 && tm < 999 ){// аналогично но для значений от 100 до 999 d1_1=tm%100; tempLEDS[2]=digits [tm/100];// Получаем разряд tempLEDS[1]=digits [d1_1/10]; // Получаем разряд tempLEDS[0]=digits [d1_1%10]; // Получаем разряд } GIE = 0;// глобальный запрет прерываний чтобы три переменных ниже записались и запись не прервалась каким нить прерыванием случайно. // ниже по сути идет описания массива LEDS чему равны его ячейки LEDS[0]= tempLEDS[2]; // значению массива LEDS с индексом 0 присваиваем значение массива tempLEDS с индексом 2, если почитать выше то будет видно что мы присваиваем посчитанные значения разрядов. LEDS[1]= tempLEDS[1]; LEDS[2]= tempLEDS[0]; GIE = 1;// врубаем прерывания заново. } //*********************************************************************** //* ОСНОВНАЯ ПРОГРАММА //*********************************************************************** void main (void) { init(); //вызывается функция init for(i=255;i>0;i--); //небольшая пауза //******** ГЛАВНЫЙ ЦИКЛ ***************** while (1) //бесконечный цикл { convert (); //в котором вызывается функция convert, ищим её выше и смотрим что в ней происходит и какие в ней функции вызываются. }; }
0 -
Прописал в инициализации T1CON = 0b00000001;
Но чето не хочет работать =) понятное дело где то ошибка у меня. Значение регистров вывожу на дисплей вижу какие то циферки мелькают.
CCPR1L, CCPR1H
Но медленно мелькают.
Так же если вывожу значение current_timer
тоже мелькают циферки.
Притом что если вывожу значение old_timer то мелькают в том же порядке. тоесть такое ощущение что две переменных равны и по сути переменная period естественно будет равна нулю если вычитать одинаковые числа друг из друга.
0 -
Осталось только контроллеру сообщить для какого из прерываний этот обработчик... ведь там несколько векторов прерываний, а на какой вешать ваш обработчик, как компилятор узнает?
я думал это общий обработчик прерываний а дальше заходит в функцию и смотрит флаги. По ним выясняет кто из прерываний вызвал.
0 -
Timer1 не забыли включить? У Вас T1CON = 0, то есть изначально таймер выключен. А если выключен, то всегда будет 0 на нём.
Да я над этим думал. но вот у меня есть другая программа и там TMR0 используется для динамической индикации и все прекрасно работает, но я не могу найти в коде где он у меня включается=))))
В начале программы надо разрешить прерывания GIE=1, т.к. они при старте программы по умолчанию выключены.Это да включено.
Я почему то посчитал, что речь о 628-м..Да извиняюсь не указал PIC 16F819
Где то тут было сообщение про мою функцию прерывания.
Она у меня выглядит так void interrupt Timer (void)
и я на самом деле понятия не имею как надо, с ней все работает в другой программе =)
Вплане мне казалось что запись void interrupt уже изначально означает функцию обработчика прерываний а Timer это лишь название которое я придумал сам.
0 -
Всетаки решил сначала разобраться с модулем CCP так как он мне пригодиться еще.
Что то делаю не так.
Вот у меня функция обработчик прерываний. Первое прерывание обрабатывается если поднят флаг CCP модулем. А он поднимает флаг по переднему фронту входного сигнала на порте RB2
Вот настройки CCP и TMR1
CCP1CON = 0b00000101; /* 7-6bit=0 (Read as 0) 5bit=0 (Младшие биты скважности. В режиме захвата не используются) 4bit=0 (Младшие биты скважности. В режиме захвата не используются) 3-0bit=0101 (0101 - Захват по каждому переднему фронту сигнала) */ //Ниже настраиваем Таймер1 для модуля захвата, работают в паре. T1CON = 0b00000000; /* 7-6bit=0 (Read as 0) 5-4bit=00 (Предделитель для TMR1 1:1) 3bit=0 (T1OSCEN Внутренний генератор выкл 0 (еслди вкл то не будут работать RB6, RB7) 2bit=0 (Синхронизация внешнего тактового сигнала Если TMR1CS=0 то значение бита игнорируется) 1bit=0 (TMR1CS выбор источника тактового сигнала. 0 - внутренний генератор) 0bit=0 (TMR1ON 0 таймер выключен) */
Ниже кусок программы по прерыванию.
void interrupt Timer (void) { if (CCP1IF){//произошло прерывание по входному сигналу на RB2 с датчика скорости, по переднему фронту GIE = 0;// глобальный запрет прерываний current_timer = CCPR1L+(CCPR1H<<8);//время между двумя импульсами period = (unsigned int)(current_timer - old_timer); old_timer = current_timer; CCP1IF = 0; GIE = 1;// разрещаем прерывания } if (TMR1IF){//если таймер TMR1 переполнился TMR1IF = 0; } if(TMR0IF) // таймер считает до такого числа которое мы указали в настройках таймера " OPTION_REG = 0b00000011; // настройки таймера 1:16 и установка Set timer TMR0 даташит page 54" и когда он досчитает он поднимает флаг, мол я досчитал! флаг TMR0IF если он равен 1 значит он поднят и выполняется тело ниже { TMR0IF=0; //сбрасывается этот же флаг чтобы он начал считать заново. Ниже текст программы для динамической индикации.
На порт RB2 в протеусе я подаю импульсы длительностью 8.75 мс, ну или период 17.6мс
Так как новичок я делаю так:
у меня в коде есть переменная, я могу ей присвоить любое число, тем самым проверяю работоспособность программы в целом. Присваиваю компилирую и гляжу выводиться ли оно на индикатор.
У меня выводиться все хорошо.
Но если подставляю ей нужную функцию то не работает. выводит 0.
Далее я методом тыка подставляю ей различные регистры переменные и тд, и смотрю их значение. Но чето везде 0 =)))
Где ошибся?
0 -
При настройке регистра T1CON если 3 бит включить то почему то перестают работать порты на выход RB4, RB6, RB7, точнее перестают управляться. Ну об этом написано в даташите. Но поясните что это за генератор такой?
Я думал это типо источник тактирования таймера TMR1
T1CON = 0b00000000; /* 7-6bit=0 (Read as 0) 5-4bit=00 (Предделитель для TMR1 1:1) 3bit=0 (T1OSCEN Внутренний генератор выкл 0 (если вкл то не будут работать RB6, RB7) 2bit=0 (Синхронизация внешнего тактового сигнала Если TMR1CS=0 то значение бита игнорируется) 1bit=0 (TMR1CS выбор источника тактового сигнала. 0 - внутренний генератор) 0bit=0 (TMR1ON 0 таймер выключен)
0
DAC модуль на PIC16f1847. Выходное аналоговое напряжение с МК. ЦАП.
в PIC
Опубликовано
там 5000 ом ? где? на выходе? тоесть если выход ЦАП подключу к земле через 1 ком то что я получу? делитель 5 и 1 ком?