Вот я написал Код.
С частотой 40кГц считывается АЦП.
На Индикатор выводится в основной программе под циклом While. Вывод на индикатор в данном случае не так важно.
Код
#include <msp430g2553.h>
unsigned int digit; /// переменная для значения 1 разряда
unsigned int pos = 1; /// номер разряда
unsigned int value; // переменная для значения выводимого числа
unsigned int buffer; // переменная для значения ADC
unsigned int i; // счетчик
void init_led(void) // инициализация индикатора (описание смотрите в даташите)
{
P1REN &= ~(BIT1+BIT2+BIT3+BIT4+BIT5+BIT6);
P2REN &= ~(BIT0+BIT1+BIT2+BIT3+BIT4+BIT5);
P2REN &= ~(BIT3+BIT4+BIT5);
P1REN &= ~BIT6;
P2DIR |= (BIT0+BIT1+BIT2);
P1DIR |= (BIT1+BIT2+BIT3+BIT4+BIT5);
P2OUT |= (BIT0+BIT1+BIT2);
P1OUT |= (BIT1+BIT2+BIT3+BIT4+BIT5);
P2DIR |=(BIT3+BIT4+BIT5);
P1DIR |=BIT6;
P2OUT |=(BIT3+BIT4+BIT5);
P1OUT |=BIT6;
}
void clear_led(void) { // обнуление. выключаем все регистры и цифры.
P2OUT |= (BIT0+BIT1+BIT2);
P1OUT |= (BIT1+BIT2+BIT3+BIT4+BIT5);
P2OUT |= (BIT3+BIT4+BIT5);
P1OUT |= BIT6;
}
void show_number(number) { // сопоставление ножек установки числа
switch (number) {
case 0 :
P1OUT &=~(BIT1+BIT2+BIT3+BIT5);
P2OUT &=~(BIT0+BIT2);
break;
case 1:
P1OUT &=~(BIT3+BIT5);
break;
case 2:
P1OUT &=~(BIT1+BIT3+BIT4);
P2OUT &=~(BIT0+BIT2);
break;
case 3:
P1OUT &=~(BIT1+BIT3+BIT4+BIT5);
P2OUT &=~(BIT0);
break;
case 4:
P1OUT &=~(BIT2+BIT3+BIT4+BIT5);
break;
case 5:
P1OUT &=~(BIT1+BIT2+BIT4+BIT5);
P2OUT &=~(BIT0);
break;
case 6:
P1OUT &=~(BIT1+BIT2+BIT4+BIT5);
P2OUT &=~(BIT0+BIT2);
break;
case 7:
P1OUT &=~(BIT1+BIT3+BIT5);
break;
case 8:
P1OUT &=~(BIT1+BIT2+BIT3+BIT4+BIT5);
P2OUT &=~(BIT0+BIT2);
break;
case 9:
P1OUT &=~(BIT1+BIT2+BIT3+BIT4+BIT5);
P2OUT &=~(BIT0);
break;
}
}
void show_registr(registr) { // сопоставление ножек управления регистра
switch (registr) {
case 4:
P1OUT &=~BIT6;
break;
case 3:
P2OUT &=~BIT5;
break;
case 2:
P2OUT &=~BIT4;
break;
case 1:
P2OUT &=~BIT3;
break;
}
}
void init_ADC(void) {
ADC10CTL1 |= CONSEQ_0; // single channel, single conversion
ADC10CTL1 |= INCH_0
+ SHS_0 // use ADC10SC bit to trigger sampling
+ ADC10DIV_3 // clock divider = 4
+ ADC10SSEL_3; // clock source = SMCLK
ADC10CTL0 |= SREF_0 // reference voltages are Vss and Vcc
+ ADC10SHT_3 // 64 ADC10 clocks for sample and hold time (slowest)
+ ADC10ON
+ ENC;
ADC10AE0 = BIT0; // Разрешаем вход АЦП на порту P1.0
}
void ConfigClocks(void)
{
BCSCTL1 = CALBC1_16MHZ; // Set range
DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation
}
void ConfigTimerA(void)
{
TACCR0 = 50; // Обеспечиваем обращение к прерыванию 16MHZ/ 8 / 50 = 40kHz
TACCTL0 = CCIE; // Разрешаем прерывание таймера по достижению значения CCR0.
TACTL = TASSEL_2 + ID_3 + MC_1;
}
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
ConfigClocks();
ConfigTimerA();
init_led();
init_ADC();
_BIS_SR(GIE);
while (1)
{
if (value == 0) {
value=buffer; // присваиваем результат к АЦП
pos = 1;
}
digit = value % 10; /// взятие остатка от деления
clear_led();
show_number(digit); // выбор числа
show_registr(pos); // выбор сегмента
value /= 10; // деление без остатка. отбпрасываем число которое показали
pos++;
}
}
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_CC0 (void)
{
/////////////////////////////////////C Частотой 40кГц работает ADC///////////////////////
ADC10CTL0 |= ADC10SC; // включаем считвание с ацп
while (ADC10CTL1 & ADC10BUSY); // ждем пока все считает
buffer = ADC10MEM;
/////////////////////////////////////////////////////////////////////////////////////////
}
Вопросы:1.Что делаю неправильно ?
2.В дальнейшем я планирую сделать фильтрацию частоты 15кГц. Т.е. счиитывается с частотой 40кГц а я ППФ спроектирую которsй будет вырезать где то 15кГц +-300Гц. И собственно вопрос. Сколько у меня запас по отсчетам есть микропроконтроллера до следующего считывания АЦП и так чтоб мигание вело себя корректно.
3.
Цитата
Если нужны точные частоты и временные интервалы, то лучше поставить кварцевый резонатор.
Не совсем понял что это за резонатор. Исходя из мануала я вычитал что это какой то генератор. Но в чем он лучше ?
4.Как настроить второе прерывание с другой частотой ? По CC1 сравнивал чтоб в другом прерывании код выполнял. В описании g2553h есть такой пункт. Но что то он не работает.А в мануале не написано как настроить сравнение с CC1.
Сейчас while(1) выводит информацию на индикатор(с прерыванием на АЦП).
НО! Я хочу и не спрашивайте почему (для практики) сделать так чтоб :
-buffer - Значение АЦП меняется с частотой 40кГЦ
-value - то значение что выводится на индкатор (=buffer_2)
-buffer_2 - с частотой 20Гц(примерно) = buffer
пока реализовано это в том же прерывании
Код
if (i==40000/10) {
i=0;
buffer_2=buffer;
}
i++;
Но хочу чтоб было в отдельном прерыании, просто для практики
Сообщение отредактировал Niketa - Feb 7 2014, 13:49