Atmega8 и TLC5947

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Родился
Сообщения: 2
Зарегистрирован: Ср июн 23, 2010 00:55:15

Сообщение striker »

Здравствуйте!

Пытаюсь завести драйвер светодиодов TLC5947 на atmega8, написал следующий код:

Код: Выделить всё

/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.8 Professional
Automatic Program Generator
© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date    : 01.05.2010
Author  : striker                         
Company : home                            
Comments: 


Chip type           : ATmega8
Program type        : Application
Clock frequency     : 8,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/

#include <mega8.h>  
#include <stdio.h>
#include <spi.h>
        
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE 3
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;
     
unsigned int red, green, blue;
            
#define XTAL_FREQ 11059200

void delay_ms_xtal(long del)
{
    unsigned int tmp;
    while (del--) {
        for (tmp = 0; tmp < XTAL_FREQ/8333; tmp++);
    }
}

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
    char status,data;
    status = UCSRA;
    data = UDR;
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) {
        rx_buffer[rx_wr_index] = data;
        if (++rx_wr_index == RX_BUFFER_SIZE) {
            rx_wr_index = 0;   
            
            red = (int)rx_buffer[0]; 
            green = (int)rx_buffer[1];
            blue = (int)rx_buffer[2]; 
            
            //printf("buffer = %s, rgb: %d, %d, %d,\r\n", rx_buffer, red, green, blue);
        }
        
        if (++rx_counter == RX_BUFFER_SIZE) {
            rx_counter=0;
            rx_buffer_overflow=1;
        };
    };
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void) {
    char data;
    while (rx_counter==0);
    data = rx_buffer[rx_rd_index];
    if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
    #asm("cli")
    --rx_counter;
    #asm("sei")
    return data;
}
#pragma used-
#endif

// Declare your global variables here

void main(void)
{
    // Declare your local variables here
         
    int i;       
    char spi_data;
    
    // Input/Output Ports initialization
    PORTB=0x00;
    DDRB=0x2C;

    PORTC = 0x00;
    DDRC = 0xFF;

    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    MCUCR=0x00;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x00;

    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: On
    // USART Mode: Asynchronous
    // USART Baud Rate: 9600 (Double Speed Mode)
    UCSRA=0x02;
    UCSRB=0x98;
    UCSRC=0x86;
    UBRRH=0x00;
    UBRRL=0x67;

    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;
          
    // SPI initialization
    // SPI Type: Master
    // SPI Clock Rate: 2*2000,000 kHz
    // SPI Clock Phase: Cycle Start
    // SPI Clock Polarity: High
    // SPI Data Order: LSB First
    SPCR=0x7C;
    SPSR=0x01;
    
    // Global enable interrupts
    #asm("sei")
    
    red = 0;
    blue = 0;
    green = 0;
    
    while (1) {
        for (i = 0; i < 32; i++) {
            printf("sending spi: %d\r\n", i);
            spi_data = spi(i);
            printf("spi_data = %d\r\n", spi_data);
            delay_ms_xtal(200);    
        }
        PORTC.0 = 1;
        PORTC.0 = 0; 
        
        printf("XLAT GO!\r\n");
        delay_ms_xtal(2000);   
    };
}
Дебажу по USART. Проблема в том, что не происходит совсем ничего! XLAT TLC5947 подключен к 23 ноге атмеги8 (PORTC.0)
У кого-нибудь есть опыт работы с подобными драйверами?


p.s. в листинге много рудиментарного кода. вырезать не стал, чтобы не отрезать чего-нибудь важного. простите, если что.
Реклама
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1287
Зарегистрирован: Пн окт 13, 2008 11:45:54
Откуда: РФ, Крым, г.Бахчисарай

Сообщение Danko »

Я с TLC5947 дела не имел и по сему на Ваш вопрос отвечу вопросами:

что такое TLC5947 ? это 24 разрядный драйвер с 12 битным ШИМ ?

и в него нужно отправить 24 двенадцатибитных значения ?

А что Вы в него отправляете ?

32 восьмибытных ?

И по чему в CVAVR не использовать библиотечные задержки ? Вы уверены что Ваш пустой цикл компилятор не выбросит ?
Первое, что привлекает в программировании, объяснить просто: ты говоришь компьютеру что то сделать, и он это делает. Безошибочно. Всегда. Без возражений.
---------------------
Линус Торвальдс. "Just for fun. Рассказ нечаянного революционера"
Контактная информация:
Реклама
Родился
Сообщения: 1
Зарегистрирован: Ср июн 23, 2010 07:08:03

Сообщение voodoopr »

Danko писал(а): И по чему в CVAVR не использовать библиотечные задержки ? Вы уверены что Ваш пустой цикл компилятор не выбросит ?
CVAVR, как и IAR и Keil при выключенной оптимизации не выкидывает ничего, и такая функция задержки прекрасно работает.
Родился
Сообщения: 2
Зарегистрирован: Ср июн 23, 2010 00:55:15

Сообщение striker »

Danko писал(а):Я с TLC5947 дела не имел и по сему на Ваш вопрос отвечу вопросами:

что такое TLC5947 ? это 24 разрядный драйвер с 12 битным ШИМ ?
24-канальный, если быть точным

Danko писал(а):и в него нужно отправить 24 двенадцатибитных значения ?

А что Вы в него отправляете ?

32 восьмибытных ?
Опс. Надо отправить 36 раз по 8 бит, чтобы получилось 24*12 = 288.
Так? И после этого дергать XLAT у микрухи?
Danko писал(а):И по чему в CVAVR не использовать библиотечные задержки ? Вы уверены что Ваш пустой цикл компилятор не выбросит ?
не выбросит, работает. библиотечный delay плохо влияет на прерывания
Реклама
Эиком - электронные компоненты и радиодетали
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1287
Зарегистрирован: Пн окт 13, 2008 11:45:54
Откуда: РФ, Крым, г.Бахчисарай

Сообщение Danko »

striker, похоже Вы неплохо разбираетесь в этом вопросе.

Если не работает может задачу раздробить на кусочки.

Первое: отключить все лишнее (в т.ч. USART и SPI)

2. сделать програмный сдвиговый регистр на 12, поморгать светодиодами.

3. заработает - переделать на SPI.

4. заработает SPI - подключать USART.
Первое, что привлекает в программировании, объяснить просто: ты говоришь компьютеру что то сделать, и он это делает. Безошибочно. Всегда. Без возражений.
---------------------
Линус Торвальдс. "Just for fun. Рассказ нечаянного революционера"
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса

Сообщение clawham »

РАССКАЗЫВАЮ СВОЙ ОПЫТ!
игрался с TLC 5940!!!
Значить какой там прикол!
каждые 4096 тактов на входной тактовой ноге нужно ПЕРЕДЕРНУТЬ СБРОС - тоесть BLANK !!!!
Он не считает по кругу .... нужно каждый раз дёргать сброс встроенного счетчика!!!

пример:

Код: Выделить всё

//шаблоны для подключенных лампочек и пинов ШИМки
#define BLANK PORTC.5
//#define BLANK2 DDRC.5
#define XLAT  PORTC.2

void timer()
{
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 16000,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: On
TCCR1A=0x00;
TCCR1B=0x09;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x3E;
OCR1AL=0x80;
OCR1BH=0x10;
OCR1BL=0x00;
}

// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
// Place your code here
    //BLANK = 1;
    //BLANK = 0;
    if(++mSec>=60000)
    {
        mSec = 0;
        ++Sec;
    }
    //OCR1BH=0x10;
    OCR1B-=0x3E80;
    //TCNT1 = 0x0000;
    //TCCNT1l = 0x00;
}

// Timer 1 output compare B interrupt service routine
interrupt [TIM1_COMPB] void timer1_compb_isr(void)
{
// Place your code here
    //BLANK = 0;
    BLANK = 1;
    BLANK = 0;
    //if(OCR1BH=0xF0
    OCR1B+=0x1000;
    //TCNT1H=0x00;
    //TCNT1L=0x00;
    //TCNT1 = 0x0000;
    //TCCNT1l = 0x00;
}

void PWM()
{
            // тестувый кусок - попробуем манипулировать моей ШИМкой
            //BLANK = 1;
            //BLANK = 0;            
            //temp = mSec%4096;
            /*
            unsigned int PWM_Chg[4]            = {0,0,0,0};       // переменная для задания уровня PWM зарядного канала
            unsigned int PWM_DisChg[4]         = {0,0,0,0};       // переменная для задания уровня PWM разрядного канала
            */
            //PWM_Oth[3] = mSec&0x0FFF;
            
            // присвоение 12-тибитных переменных зарядки каждому каналу
            a2[0] = PWM_Chg[3]>>4;                                  // начало 15-го канала
            a2[1] = ((PWM_Chg[3]&0x0F)<<4)+(PWM_Chg[2]>>8);         // конец 15-го начало 14-го
            a2[2] = PWM_Chg[2];                                     // конец 14-го канала
            
            a2[3] = PWM_Chg[1]>>4;                                  // начало 13-го канала
            a2[4] = ((PWM_Chg[1]&0x0F)<<4)+(PWM_Chg[0]>>8);         // конец 13-го начало 12-го
            a2[5] = PWM_Chg[0];                                     // конец 12-го канала

            // каналы разрядки
            a2[6] = PWM_DisChg[3]>>4;                               // начало 11-го канала
            a2[7] = ((PWM_DisChg[3]&0x0F)<<4)+(PWM_DisChg[2]>>8);   // конец 11-го начало 10-го
            a2[8] = PWM_DisChg[2];                                  // конец 10-го канала
            
            a2[9] = PWM_DisChg[1]>>4;                               // начало  9-го канала
            a2[10] = ((PWM_DisChg[1]&0x0F)<<4)+(PWM_DisChg[0]>>8);  // конец  9-го начало  8-го
            a2[11] = PWM_DisChg[0];                                 // конец  8-го канала

            // растановка остальных каналов PWM
            a2[12] = PWM_Oth[7]>>4;                                 // начало  7-го канала
            a2[13] = ((PWM_Oth[7]&0x0F)<<4)+(PWM_Oth[6]>>8);        // конец  7-го начало  6-го
            a2[14] = PWM_Oth[6];                                    // конец  6-го канала

            a2[15] = PWM_Oth[5]>>4;                                 // начало  5-го канала
            a2[16] = ((PWM_Oth[5]&0x0F)<<4)+(PWM_Oth[4]>>8);        // конец  5-го начало  4-го
            a2[17] = PWM_Oth[4];                                    // конец  4-го канала

            a2[18] = PWM_Oth[3]>>4;                                 // начало  3-го канала
            a2[19] = ((PWM_Oth[3]&0x0F)<<4)+(PWM_Oth[2]>>8);        // конец  3-го начало  2-го
            a2[20] = PWM_Oth[2];                                    // конец  2-го канала
            
            a2[21] = PWM_Oth[1]>>4;                                 // начало  1-го канала
            a2[22] = ((PWM_Oth[1]&0x0F)<<4)+(PWM_Oth[0]>>8);        // конец  1-го начало  0-го
            a2[23] = PWM_Oth[0];                                    // конец  0-го канала

            // отключаем моник 3310
            PORTB.4 = 1;
            SPCR=0x50;
            SPSR=0x01;            
  
            // грузим значения GSCALE
            spi(a2[0]);
            spi(a2[1]);
            spi(a2[2]);
            spi(a2[3]);
            spi(a2[4]);
            spi(a2[5]);
            spi(a2[6]);
            spi(a2[7]);
            spi(a2[8]);
            spi(a2[9]);
            spi(a2[10]);
            spi(a2[11]);
            spi(a2[12]);
            spi(a2[13]);
            spi(a2[14]);
            spi(a2[15]);
            spi(a2[16]);
            spi(a2[17]);
            spi(a2[18]);
            spi(a2[19]);
            spi(a2[20]);
            spi(a2[21]);
            spi(a2[22]);
            spi(a2[23]);

            
            
            //клацаем триггер загрузки на выход
            XLAT = 1;
            delay_us(15);
            XLAT = 0;
            
            // вырубаем двойную скорость
            SPCR=0x50;
            SPSR=0x00;
            
            // врубаем моник
            PORTB.4 = 0;
}

не уверен точно что с прерываниями таймера 1 всё так просто!
тактование XTAL берется от кварца меги - у меня стоял 16 мегагерц...хотел 32 мегагерца...и заставить таймер меги работать от внешнего такта - нифига...32 мегагерца для меги 32 неподъёмная скорость...:( а жаль...он крутой....термостабилизированный...мощный...ну в общем у меня получилось так...
если нужно получить больше частоту ШИМа то нужно BLANK lthufnm не каждые 4096 такта а например 2048 - эт в два раза увеличим такт(у меня получилось по полной - 4.8 килогерца...) микруха греется как сабака!!! адже если на выходах ничего нет....хотя выходы я грузил резюками в 200 омм и ULQ2003 - а дальше на затворы полевиков.... зарядка у меня такая...правда ещё в процессе....
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Реклама
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»