Например, настраиваем прерывание окончания преобразования АЦП, режим измерения АЦП - одиночный, запускаем измерение и засыпаем. Как только МК получит результат, то проснется и прыгнет в обработчик. Там уже забираем результат и творим с ним все что душа пожелает.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
$regfile = "m324pdef.dat" 'для чипа ATMega324p
'$regfile = "m644def.dat" 'для чипа ATMega644
Dim Dadc As Word 'данные АЦП (внутреннего)
Dim Ua As Single 'временное значение
Dim Ub As Single 'временное значение
On Adcc Adc_int Nosave 'вектор прерывания от АЦП
'...
' АЦП
'Admux = &B00011111 'внешняя опора АЦП со входа AREF, внутренняя выключена
'измерение на закороченном входе
'...
' измерение с помощью внутреннего АЦП. результат в Ua, выраженный в Вольтах шкалы
Adcsr = &B10001110 'разрешить АЦП с частотой тактирования F / 64
'в режиме с естественным положением битов, прерывание разрешено
'-------
For Tmpb = 1 To 16 'произвести 16 измерений
Set Adcsr.6 'запустить АЦП
Rdiadc1:
Idle 'останов
If B_adc = 0 Then 'есть данные внутреннего АЦП?
Goto Rdiadc1 'нет - повторить
End If
Next Tmpb
Adcsr = &B00000110 'запретить АЦП
Dadc = Dadc - 25 'коррекция смещения нуля
Ua = Dadc : Dadc = 0 'в формат с плавающей точкой, а исходный очистить
Ua = Ua * 0.0003052 'привести к шкале 0...5 В
Return
'обработка прерывания от внутреннего АЦП
Adc_int:
$asm
Push R31 'сохраним регистры
In R31 , Sreg
Push R31
Push R30
Push R29
'-----
'считать данные внутреннего АЦП
lds R29 , {Dadc} 'считать сумму
Lds R30 , {Dadc + 1}
' In R31 , Adcl 'считать показания (M32)
lds R31 , Adcl 'считать показания (M644)
Add R29 , R31 'добавить к сумме показания АПЦ
' In R31 , Adch ' (M32)
LDS R31 , Adch ' (M644)
Adc R30 , R31
Sts {Dadc} , R29
Sts {Dadc + 1} , R30
'-----
Ldi R31 , 255 'есть данные внутреннего АЦП
Sts {B_adc} , R31
'-----
Adcinte:
Pop R29 'восстановим регистры
Pop R30
Pop R31
Out Sreg , R31
Pop R31
Reti
$end Asm
Return
Только вместо Idle было предложение использовать ADC Noise Canceler
Добрый день.
Недавно начал заниматься микроконтроллерами столкнулся вот с проблемой.
На Attiny261 пытаюсь реализовать ШИМ на Timer1 и внешнее прерывание Int0.
Долго мучился с ШИМ, напрмую Config не настраивает ШИМ. Настроил через регистры. Внешнее прерывание тоже работает. Вся загвозка в функции Waitms при включенном ШИМ она неверно отсчитывает время.
Если регистры Tccr1a и Tccr1b закоментить то все работает иначе программа замирает на Waitms.
Ощущение что Waitms организована на первом таймере..
Никто не сталкивался с подобным?
Разобрался, пост можно удалить... Оказывается дело было в протеусе))
Последний раз редактировалось dikras Пн май 21, 2012 11:22:08, всего редактировалось 1 раз.
Всем Привет! Я начинающий...Есть такая задачка , на контроллер подавать сигнал с генератора, а на выходе чтобы частота менялась синхронно со входным. Вот код, но не работает в Протеусе. Входной сигнал подаю на pin ICP1 PD6. Подскажите спецы, что не так...
С уважением.
Просто не забывайте, что Вы настроили прерывание по захвату счетного регистра. И если частота подаваемого сигнала высокая, то таймер даже пискнуть не успеет. И Протеус тут совершенно не при чем...
P.S. Кстати, измеряет верно. Между импульсами таймер насчитал 1149 котов тиков. С делителем 1024 и тактовой частотой 4 MHz один тик таймера равен 1024 / 4 000 000 = 0,000256 c. Умножаем и получаем период 1149 * 0,000256 = 0,294144 c. Ну и частота в итоге равна 1 / 0,294144 = 3,40 Hz Собственно, что на генераторе и установлено.
Здравствуйте уважаемы коты..... Вопрос такой: - Непонятно как отключать будильник в ds3231 по заданному времени с кнопок? А с включением будильника разобрался.......
Вы меня неправильно поняли, я имел ввиду микросхеме есть два alaram (таймера), я думаю так если первый таймер запустить то при совпадение значение регистров часов и значение регистров alaram (таймера 1) то на 7 ноге будет логический ноль, то есть включится. А что бы отключить alaram (таймера 1) надо думаю запустить alaram (таймера 2), вот тут я и запутался может что не так я по описанию микросхемы неправильно понял, поправьте пожалуйста мою мысль...............
edm2007 писал(а):Да понять-то понял, просто ослоумничаю.
cattus писал(а):то на 7 ноге будет логический ноль, то есть включится
Мда? А судя по распиновке, ноги 5 - 12 никуда не подключены, и должны быть посажены на землю.
Перепутал я 3 нога на int, а не 7 Похоже додумал надо задействовать флаги регистров Status Register (0Fh) и Control Register (0Eh) тогда должно получиться остановить alaram в нужное нам время
edm2007 подскажите где я не допонимаю, взял Ваш код сдвигового регистра с переделкой под Mega 32 и на два индикатора с общим анодом (в принципе не существенно, что попалось в протеусе).
Я так понял проталкиваем первым разряды, затем цифры 1 и 2 индикатора? на Протеусе 1 разряд не горит остальные светятся, но больше похоже на статическую индикацию нежели динамическую....
Или опять протеус шалит?
$regfile = "m32def.dat" ' тип МК
$crystal = 16000000 ' выбор кристала для расчета задержек
'*****************************************[Определение переменных и констант]************************************
Dim Count As Byte ' переменная для работы с индикацией
Dim Ledout As Byte ' переменная 1 для загрузки в регистры сдвига
Dim Ledout2 As Byte ' переменная 2 для загрузки в регистры сдвига
Dim Number(4) As Byte ' значения 4 разрядов
Dim H_flag(4) As Byte ' флаги точек 4 разрядов
Dim Blink_count As Word ' счетчик времени мигания
Dim Blink_flag(4) As Byte ' флаги мигания разрядов
'***********************************************[Инициализация портов]*******************************************
Ddrc = &B11111111 'порт С на выход
'*********************************************[Инициализация прерываний]*****************************************
Config Timer0 = Timer , Prescale = 64 ' конфигурируем таймер индикации
On Ovf0 Refresh ' метка на прерывание индикации
Enable Interrupts ' разрешаем прерывания
Enable Ovf0 ' и для индикации в частности
'********************************************[Присвоение уникальных имен]****************************************
595clock Alias Portc.0 : 595data Alias Portc.1 ' выводы 74HC595
'*********************************************[Начало основной программы]****************************************
Number(1) = 1 '
Number(2) = 2
Number(3) = 3
Number(4) = 4
Blink_flag(1) = 1 ' мигаем первым и шестым разрядом
'Blink_flag(4) = 1
'-------------------------
Do
Loop
'***********************************[Процедуры обработки подпрограмм и прерываний]*******************************
Refresh: ' прерывание таймера Т0
If Blink_flag(count) = 1 And Blink_count > 200 Then ' если флаг мигания выставлен и счетчик > 200
Ledout = Lookup(1 , Rank) ' выключаем разряд
Else ' иначе (флаг не выставлен, либо счетчик < 200)
Ledout = Lookup(count , Rank) ' забираем в переменную номер разряда
End If
Shiftout 595data , 595clock , Ledout , 1 ' закидываем в регистр
'----------------------------------------------------------------------------------------------------------------
Incr Count : If Count > 4 Then Count = 1 ' выбираем разряд для загрузки
Incr Blink_count : If Blink_count > 400 Then Blink_count = 1 ' длительность мигания
Ledout = Lookup(number(count) , Digits) ' забираем в переменную код цифры
If H_flag(count) = 1 Then ' управление точками индикатора
Ledout = Ledout Xor &B11011111
End If
Shiftout 595data , 595clock , Ledout , 1 ' закидываем в регистр
'----------------------------------------------------------------------------------------------------------------
Ledout2 = Lookup(number(count) , Digits) ' забираем в переменную код цифры
If H_flag(count) = 1 Then ' управление точками индикатора
Ledout2 = Ledout2 Xor &B11011111
End If
Shiftout 595data , 595clock , Ledout , 1 ' закидываем в регистр
Pulseout Portc , 2 , 20 ' защелкиваем данные (для 8МГц импульс 5мкс)
Return
'******************************************************[DATA]****************************************************
Digits: ' цифры
Data &B11000000 , &B11111100 , &B10100100 , &B10110000 , &B10011001 ' 0 1 2 3 4
'-------------------------
Rank: ' разряды
'Data &B00000000 ' выкл
Data &B00000001 , &B00000010 , &B00000100 ' 1 2 3
Data &B00001000 , &B00010000 , &B00100000 ' 4 5 6
Проект протеуса будьте добры. Пока я только вижу что Вы изменив тактовую частоту, наплевали и на расчет частоты обновления индикатора, и на прочие зависимые вещи.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Выше выложил...когда читаешь вроде все понимаю, стоит попробовать всегда какие то затыки, прям закон Мура
Вы наверное про эти расчеты Pulseout Portc , 2 , 20
А, ну это Вы вообще все изменили. Я пока нихрена понять не могу, что должно быть. Тут Вам проще свою обработку написать, Вам же виднее как это подключение должно работать. Что же касаемо динамической индикации, то для восьми разрядов достаточно ДВУХ регистров. Сегментов 8 + разрядов 8 = 16 ног. И вообще, этот вариант писался специально для Attiny45, у которой всего 5 рабочих ног. Тут же можно например, сегменты посадить на регистр, а разрядами рулить уже с МК. Ну ног-то куча. В этом случае и обработка будет проще, и регистр будет вообще ОДИН.
P.S. У Вас сколько ног будет стабильно занято-то?
Вы наверное про эти расчеты Pulseout Portc , 2 , 20
Я про прерывание по переполнению таймера, в основном.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
If Blink_flag(count) = 1 And Blink_count > 200 Then ' если флаг мигания выставлен и счетчик > 200
Ledout = Lookup(1 , Rank) ' выключаем разряд
Else ' иначе (флаг не выставлен, либо счетчик < 200)
Ledout = Lookup(count , Rank) ' забираем в переменную номер разряда
End If
Shiftout 595data , 595clock , Ledout , 1 ' закидываем в регистр
ибо у меня по схеме они на последнем регистре,
3 регистр это для ULN2003, ноги еще будут задействоваться для ЖК Nokia 3310 или 1202, плюс кнопки, энкодер...
Последний раз редактировалось amv2000 Вс май 27, 2012 17:36:44, всего редактировалось 1 раз.
Я еще раз говорю, я делал динамическую индикацию. В этом случае все сегменты объединяются, какая разница, 6 разрядов или 8. А разряды управляются отдельно. В этом случае восемь сегментов для всех индикаторов и восемь разрядов для управления. Итого - 16 ног. У регистра 8 ног. Значит требуется два регистра ровно, для восьми разрядов.
Я ведь даже в статье писал:
Вообще два регистра способны обслужить 8 разрядов, но в моем распоряжении были только такие индикаторы.
"Слишком много людей ломаются, даже не подозревая о том, насколько близки к успеху они были в тот момент, когда упали духом". Томас Алва Эдисон
Хорошо ставим два регистра на одну половину разряды одного индикатора на другую второго, далее я смутно представляю вводим две метки Rank: или же в этой же прописываем