Поклонники продукции Microchip Technology Inc тусуются тут.
Ответить

RGB_ночник на PIC16f676, нужна помощь с кодом

Сб дек 05, 2020 17:14:43

Доброго здравия всем откликнувшимся. Нашёл у себя в закромах два 16f676. С пиками никогда дела и малейшего не имел, думал выкинуть, но рука не поднялась. А потом решил сделать хоть ночничек какой-нить. Нашел исходник RGB ночника но на attiny13, решил портировать его, но чегото я делаю не так с кодом, ничего не запустилось, хотя вроде настроил и проинициализировал всё правильно.
Подскажите в чем причина может быть. Заранее спасибо!
Спойлер
Код:
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RA3/MCLR pin function select (RA3/MCLR pin function is MCLR)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#define _XTAL_FREQ 4000000
#include <pic.h>
#include <xc.h>
#define OUT_R RC4
#define OUT_G RC3
#define OUT_B RC2
#include <stdlib.h>

unsigned int rgb_r=0,rgb_g=0,rgb_b=0;
unsigned int count=0;
unsigned int r=0,g=0,b=0;
unsigned int step=0;
// Timer 0 overflow interrupt service routine
void __interrupt() Timer0_ISR(void){
 count++;
 //канал красного
 if (count == 0)
 { //если счетчик переполнился и принял значение 0
 rgb_r = r; //сохранием значения в буфер
 OUT_R =1; //выставляем ноги, отвечающие за ШИМ в логическую 1
 }
 if (rgb_r == count) { OUT_R = 0;}//по достижении заданной скважности выводим 0
 // канал зелёного
 if (count == 0)
 { //если счетчик переполнился и принял значение 0
 rgb_g = g; //сохранием значения в буфер
 OUT_G =1; //выставляем ноги, отвечающие за ШИМ в логическую 1
 }
 if (rgb_g == count) { OUT_G = 0;}//по достижении заданной скважности выводим 0
 // канал синего
 if (count == 0)
 { //если счетчик переполнился и принял значение 0
 rgb_b = b; //сохранием значения в буфер
 OUT_B =1; //выставляем ноги, отвечающие за ШИМ в логическую 1
 }
 if (rgb_b == count) { OUT_B = 0;}//по достижении заданной скважности выводим 0
 
}

void main(void)
{



 
PORTC=0b000000;
TRISC=0b000000;
OPTION_REG=0x01;
INTCON=0b101000;


while (1)
 {
 /*
 По-умолчанию формулу R-G-B начнем с красного цвета 255-0-0.
1) Наращивается зеленый цвет 255-1-0, 255-2-0 ... 255-255-0.
2) Уменьшается красный цвет 254-255-0, 253-255-0 ... 0-255-0.
3) Наращивается синий цвет 0-255-1, 0-255-2 ... 0-255-255.
4) Уменьшается зеленый цвет 0-254-255, 0-253-255 ... 0-0-255.
5) Наращивается красный цвет 1-0-255, 2-0-255 ... 255-0-255.
6) Уменьшается синий цвет 255-0-254, 255-0-253 ... 255-0-0.
 */

 if(step==0)
 {
 step=1;
 }
 if(step==1)
 {
 r++; g=0;b=0;
 if(r>=255){step=2;}
 }
 if(step==2)
 {
 g++;
 if(g>=255){step=3;}
 }
 if(step==3)
 {
 r--;
 if(r<=0){step=4;}
 }
 if(step==4)
 {
 b++;
 if(b>=255){step=5;}
 }
 if(step==5)
 {
 g--;
 if(g<=0){step=6;}
 }
 if(step==6)
 {
 r++;
 if(r>=255){step=7;}
 }
 if(step==7)
 {
 b--;
 if(b<=0){step=0;}
 }
 __delay_ms(30);
 }

}

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб дек 05, 2020 17:42:39

Дайте ссылку на исходный проект для тиньки.

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб дек 05, 2020 17:45:10

Может отсюда ….

Изображение

Код не смотрел

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб дек 05, 2020 17:59:41

NStorm, вот исходник для тиньки
Спойлер
Код:
Chip type : ATtiny13
AVR Core Clock frequency: 9,600000 MHz
Memory model : Tiny
External RAM size : 0
Data Stack size : 16
*****************************************************/

#include <tiny13.h>
#include <delay.h>
#define OUT_R PORTB.3
#define OUT_G PORTB.4
#define OUT_B PORTB.2
#include <stdlib.h>

unsigned char rgb_r =0,rgb_g=0,rgb_b=0;
unsigned char count = 0;
unsigned char r=0,g=0,b=0;
unsigned char step=0;
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
 count++;
 //канал красного
 if (count == 0)
 { //если счетчик переполнился и принял значение 0
 rgb_r = r; //сохранием значения в буфер
 OUT_R =1; //выставляем ноги, отвечающие за ШИМ в логическую 1
 }
 if (rgb_r == count) { OUT_R = 0;}//по достижении заданной скважности выводим 0
 // канал зелёного
 if (count == 0)
 { //если счетчик переполнился и принял значение 0
 rgb_g = g; //сохранием значения в буфер
 OUT_G =1; //выставляем ноги, отвечающие за ШИМ в логическую 1
 }
 if (rgb_g == count) { OUT_G = 0;}//по достижении заданной скважности выводим 0
 // канал синего
 if (count == 0)
 { //если счетчик переполнился и принял значение 0
 rgb_b = b; //сохранием значения в буфер
 OUT_B =1; //выставляем ноги, отвечающие за ШИМ в логическую 1
 }
 if (rgb_b == count) { OUT_B = 0;}//по достижении заданной скважности выводим 0
 
}

void main(void)
{

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out
// State5=P State4=T State3=T State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0xFF;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 9600,000 kHz
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x01;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x02;

// Global enable interrupts
#asm("sei")
 srand(6);
while (1)
 {
 /*
 По-умолчанию формулу R-G-B начнем с красного цвета 255-0-0.
1) Наращивается зеленый цвет 255-1-0, 255-2-0 ... 255-255-0.
2) Уменьшается красный цвет 254-255-0, 253-255-0 ... 0-255-0.
3) Наращивается синий цвет 0-255-1, 0-255-2 ... 0-255-255.
4) Уменьшается зеленый цвет 0-254-255, 0-253-255 ... 0-0-255.
5) Наращивается красный цвет 1-0-255, 2-0-255 ... 255-0-255.
6) Уменьшается синий цвет 255-0-254, 255-0-253 ... 255-0-0.
 */
 
 if(step==0)
 {
 //step = rand() % 6 + 1;
 step=1;
 }
 if(step==1)
 {
 r++; g=0;b=0;
 if(r>=255){step=2;}
 }
 if(step==2)
 {
 g++;
 if(g>=255){step=3;}
 }
 if(step==3)
 {
 r--;
 if(r<=0){step=4;}
 }
 if(step==4)
 {
 b++;
 if(b>=255){step=5;}
 }
 if(step==5)
 {
 g--;
 if(g<=0){step=6;}
 }
 if(step==6)
 {
 r++;
 if(r>=255){step=7;}
 }
 if(step==7)
 {
 b--;
 if(b<=0){step=0;}
 }
 delay_ms(30);
 }
}

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб дек 05, 2020 19:00:52

Ну вас таймер на гораздо меньшей частоте на пике настроен. RAIE зачем-то включили в INTCON.
Отключите АЦП и компаратор на старте еще:
Код:
    CMCON0 = 0b111; // Disable COMPARATOR
    ANSEL = 0x00; // Disable ADC

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб дек 05, 2020 19:56:56

NStorm, Сделал как Вы сказали- результата не дало. В шпротеусе смотрю по осцилографу, на RC1-RC2 появляются импульсы одновременно длительностью гдето 10 микросекунд, а на RC0-100микросекунд.

Добавлено after 32 minutes 5 seconds:
Вроде разобрался. Нужно было флаг переполнения сбрасывать в прерывании
void __interrupt() Timer0(void){
count++;
//канал красного
if (count == 0)
{ //если счетчик переполнился и принял значение 0
rgb_r = r; //сохранием значения в буфер
OUT_R =1; //выставляем ноги, отвечающие за ШИМ в логическую 1
}
if (rgb_r == count) { OUT_R = 0;}//по достижении заданной скважности выводим 0
// канал зелёного
if (count == 0)
{ //если счетчик переполнился и принял значение 0
rgb_g = g; //сохранием значения в буфер
OUT_G =1; //выставляем ноги, отвечающие за ШИМ в логическую 1
}
if (rgb_g == count) { OUT_G = 0;}//по достижении заданной скважности выводим 0
// канал синего
if (count == 0)
{ //если счетчик переполнился и принял значение 0
rgb_b = b; //сохранием значения в буфер
OUT_B =1; //выставляем ноги, отвечающие за ШИМ в логическую 1
}
if (rgb_b == count) { OUT_B = 0;}//по достижении заданной скважности выводим 0
T0IF=0;
}

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб дек 05, 2020 20:14:57

Alek_von_German, ах да, в пиках xc8 не делает это автоматом. И еще на всякий случай - в пиках нет разных векторов прерываний, как в AVR. Тут один единственный вектор прерывания на всё. По-хорошему в ISR надо проверять флаги прерываний и по ним смотреть что нужно делать. Но это ес-но в данном случае не актуально ,если активно одно единственное прерывание.

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб дек 05, 2020 23:26:43

NStorm, ну эт я ужо понял. Углубляться в ПИКи особого желания нету, это так, для общего развития, дабы камушки не валялись почём зря.

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Чт янв 07, 2021 16:57:55

Мне кажется, что pic16f676 низкоскоростной для (до 20 Мгц) для реализации RGB светильника. У меня получилось на pic18f452 - 40 Мгц. И то при передаче данных в RGB ленту все "плотничком", ни единой свободной микросекунды.

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Чт янв 07, 2021 17:03:33

а мне хватило 8 МГц да еще с попыткой управлять яркостью через чередование в сдвиговом регистре. На 40 Мгц можно VGA забабахать, с музыкой.

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Чт янв 07, 2021 17:13:33

Смотря на чём и как писать

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб июл 03, 2021 13:57:14

http://pic24.ru/doku.php/osa/articles/vga_game
чуть больше 40, конечно, но кто считает? :))
Надо бы поизучать ОСА...

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб июл 03, 2021 14:13:35

Доброго здравия всем! Прошу прощения, что снова поднимаю данную тему, но у меня снова возникла проблема с этим кодом.
Т.к., мой прошлый компьютер приказал долго жить, а почти все программы и исходники остались на нем без возможности восстановить, свои учебные проекты пытаюсь восстановить по памяти своей(почти отсутствующей).
Так вот, вспомнил я, что делал ночник на pic16f676, код восстановил, в протеусе проверил, а в железе работает он как-то странно. Сама ШИМ работает, но паузы между вспышками слишком большие будто частота шим слишком маленькая, и выходит, что светодиоды просто перемигиваются с разной частотой. Всё проверил несколько раз, делители стоят правильно, таймер вроде тоже настроил правильно, да и вообще код считай один в один повторяет мною выложенный ранее, но если раньше он не работал из-за того, что я не сбрасывал флаг, то сейчас я даже и рядом предположить не могу...
Спойлер
Код:
#pragma config MCLRE = ON       // RA3/MCLR pin function select (RA3/MCLR pin function is MCLR)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#define _XTAL_FREQ 4000000
#include <pic.h>
#include <xc.h>
#include <stdio.h>
#include <stdint.h>
#define OUT_R RC0
#define OUT_G RC1
#define OUT_B RC2

unsigned int rgb_r=0,rgb_g=0,rgb_b=0;
unsigned char count=0;
unsigned int r=0,g=0,b=0;
unsigned char step=0;
void __interrupt() Timer0(void){
if (count == 0)
    {
        rgb_r = r;
        OUT_R =1;
    }
if (rgb_r == count) { OUT_R = 0;}
if (count == 0)
    {
        rgb_g = g;
        OUT_G =1;
    }
if (rgb_g == count) { OUT_G = 0;}
if (count == 0)
    {
        rgb_b = b;
        OUT_B =1;
    }
if (rgb_b == count) { OUT_B = 0;}
count++;
T0IF = 0;

}

int main(void)
{
    ANSEL = 0x00;
    CMCON=0x00;
    PORTC=0b000000;
    TRISC=0b000000;
    OPTION_REG=0x02;
    INTCON=0xA0;
    TMR0=0;

    while (1)
 {
 
        if(step==0)
           {
             step=1;
           }
 
        if(step==1)
           {
             r++; g=0;b=0;
            if(r>255){step=2;}
           }
 
        if(step==2)
           {
            g++;
            if(g>255){step=3;}
          }
 
        if(step==3)
          {
            r--;
            if(r<=0){step=4;}
           }

        if(step==4)
          {
             b++;
            if(b>255){step=5;}
           }
 
        if(step==5)
           {
             g--;
             if(g<=0){step=6;}
          }
         if(step==6)
           {
              r++;
              if(r>255){step=7;}
            }

        if(step==7)
          {
            b--;
            if(b<=0){step=0;}
          }
         __delay_ms(30);
  }
}

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб июл 03, 2021 15:44:57

в протеусе проверил, а в железе работает он как-то странно.

В протеусе можно измерить все тайминги и посмотреть лог. анализатором.

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб июл 03, 2021 16:06:04

otest, стыдно сказать, но я так и не понял как работает лог.анализатор в шпротеусе. Но по осциллографу я выяснил, что период составляет порядка 260mS, если я правильно владею калькулятором, то частота шим в данном случаесоставляет ~3.8Hz. Ето же нонсенс. Предделители вообще не стоят никакие, частота камня 4000000.

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб июл 03, 2021 19:04:38

Ослик для этого не годится. По лог. анализатору есть хелп. Поставь брек поинты в нужное место и протеус покажет затраченое время. Здесь по русски http://kazus.ru/forums/showthread.php?t=13198

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Сб июл 03, 2021 20:26:13

otest, спасибо за ссылку, разобрался. Частота оказалась 22 Гц.
Но вот вопрос, как она может быть таковой если частота камня 4.000.000Гц и предделители отключены?
Изображение

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Вс июл 04, 2021 10:42:05

По умолчанию для всех "среднемладших" справедливо положение, когда частота равна частоте кварца(внутреннего RC генератора) деленного на 4.
Это "особенность" ПИКовых...
Т.е. кварц 4МГц, а системная тактовая 1МГц (при 20 МГц кварце будет 5МГц максимум против 9,6МГц в тини13, при отключенном предделителе).
Единственно те модели (более современные), где PLL заложено да "энхансед" линейка позволяют частоту поднять.
8)

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Вс июл 04, 2021 15:36:46

BOB51, да, это я знаю. Мне просто интересно, что я сделал не так в этот раз, если в прошлый раз всё работало как надо. Перечитал уже всё, пересмотрел все настройки и всё равно не понятно где я туплю.

Re: RGB_ночник на PIC16f676, нужна помощь с кодом

Вс июл 04, 2021 18:28:38

Под Си вряд-ли подскажу...
В принципе... Если это не WS2812-подобные а всего 3х элементные...
Достаточно программного ШИМ с частотой от 62-120Гц. Вполне потянет любой МК...
Главная сетка частот равна периоду деленному на 256 (или более - зависит от типа МК и системы команд, имеющихся таймеров). На каждом кванте проверяем совпадение по каналам с масками задания и модифицируем вывод.
В конце периода обработка изменения данных.
:roll:
Ответить