'===============================================================================
'*
'* Автор: Sasha_1973
'* Дата: 18.12.2013 г.
'*
'* МК: ATmega328P
'* Тактовая частота МК: 7,3728 MГц
'*
'* Скорость передачи USART: 460800 бод
'*
'* Компилятор: BASCOM-AVR 2.0.7.1
'* Используемый шрифт в Bascom: Consolas; размер = 14
'*
'* Программа симулятор: Proteus 7.10 SR0
'*
'* Описание: 3 синусоиды (аппроксимация = 252 точки), смещённые по фазе на 120° + 6 АЦП (режим Free) + USART (скорость трансляции = 460800 бод) + Atmega328P
'*
'===============================================================================
$map ' Получаем карту распределения памяти
$regfile = "m328Pdef.dat" ' Используемый контроллер
' $crystal = 7372800 ' 7,3728 МГц, кварц для стабильной работы USART во всём диапазоне скоростей передачи и приёма
$crystal = 18432000 ' 18,432 МГц, кварц для стабильной работы USART во всём диапазоне скоростей передачи и приёма
$framesize = 32 'размер области используемой и необходимой для преобразований
$hwstack = 40 ' Размер аппаратного стека
$swstack = 16 ' Размер программного стека
$baud = 230400 '1200 '2400 '4800 '9600 '19200 '38400 '57600 '115000 '230400
Ucsr0a.1 = 1 ' Двойная скорость работы USART, скорость трансляции = $baud * 2
'---------------------- Настройка TIMER1 -------------------------------------
Config Timer1 = Timer , Clear Timer = 1 , Prescale = 1
On Compare1a Обработка_прерывания_compare1a Nosave
Stop Timer1
'---------------------- Настройка TIMER0 -------------------------------------
Config Timer0 = Pwm , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1
Stop Timer0
'---------------------- Настройка TIMER2 -------------------------------------
Config Timer2 = Pwm , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 1
Stop Timer2
'---------- Конфигурация АЦП, измерения проходят в фоновом режиме ------------
' Config Adc = Free , Prescaler = 128 , Reference = Avcc
Admux = &B01000000
Adcsra = &B11001111
Adcsrb = &B0000000
On Adc Обработка_прерывания_ацп Nosave
'------------------- Используемые переменные ---------------------------------
Dim Цикл_print As Byte
Dim Цикл_значение_синуса As Byte
'------- Для генератора 3-х фазной синусоиды, фазы смещены на 120° -----------
Dim 1_фаза As Byte
Dim 2_фаза As Byte
Dim 3_фаза As Byte
Dim Значение_синуса(253) As Byte
Dim Значение_синуса_1_фаза As Byte
Dim Значение_синуса_2_фаза As Byte
Dim Значение_синуса_3_фаза As Byte
'------------- Для 6-ти каналов АЦП ------------------------------------------
Dim Данные_ацп(6) As Word
Dim Temp_данные_ацп As Word
Dim Сырые_данные_ацп(2) As Byte At Temp_данные_ацп Overlay
'\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
'------------------ Запуск и предварительные настройки -----------------------
'\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
'------ Закидываем значения выводимой синусоиды из таблицы в оперативку ------
For Цикл_значение_синуса = 0 To 251
Значение_синуса(цикл_значение_синуса + 1) = Lookup(цикл_значение_синуса , Таблица_синуса_252)
Next Цикл_значение_синуса
'------ Делаем смещение фаз на 120° ------------------------------------------
Значение_синуса_1_фаза = 0 ' 1 фаза
Значение_синуса_2_фаза = 84 ' 2 фаза
Значение_синуса_3_фаза = 168 ' 3 фаза
'Для 252 точек. Значение для получения частоты 50,00 Гц, при частоте кварца 7,3728 Мгц
' Compare1a = 580
Compare1a = 1462
'------ Запускаем аппаратные средства контроллера ----------------------------
' Start Adc
Start Timer0
Start Timer1
Start Timer2
'\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
'-------------- Разрешаем работу необходимых прерываний ----------------------
' Enable Adc
Enable Compare1a
'------------ Разрешаем работу всех включенных прерываний --------------------
Enable Interrupts
'Ждём первого измерения АЦП, последующие измерения происходят в фоновом режиме
' Power Adcnoise
'===============================================================================
' Г Л А В Н Ы Й Ц И К Л
'===============================================================================
Главный_цикл:
nop
For Цикл_print = 1 To 6
Print "Тест АЦП " ; Цикл_print ; ": " ; Данные_ацп(цикл_print)
Next Цикл_print
Print
Waitms 20
Goto Главный_цикл
End
'===============================================================================
' П О Д П Р О Г Р А М М Ы
'===============================================================================
'===============================================================================
Обработка_прерывания_compare1a:
'-------------------------------------------------------------------------------
nop
'------ Сохраняем используемые регистры и SREG -------
!push R26
!in R26 , sreg
!push r26
!push R10
!push R11
!push R27
!push R30
!push R31
'------ Высчитываем выводимое значение синуса для 1 фазы -------
!lds R26 , {Значение_синуса_1_фаза}
!inc R26
'----- Исключаем переполнение счетчиков значений синуса, для 252 точек -------
!cpi R26 , &HFC ' десатичное = 252, двоичное = &B11111100
!BRLO Выход_значение_синуса_1_фаза ' Перейти если меньше
!Lds R26 , 1 ' Если равно или больше закидываем в регистр "1"
Выход_значение_синуса_1_фаза:
!sts {Значение_синуса_1_фаза} , R26 ' Пишем значение регистра в переменную
'------ Забираем значение синуса из массива, всего 252 значения -------
Loadadr Значение_синуса(значение_синуса_1_фаза + 1) , Z
!ld R26 , Z ' Забираем текущее значение синуса из массива в регистр
'------ Закидываем полученное значение в регистр таймера -------
!out Ocr0a , R26
'------ Высчитываем выводимое значение синуса для 2 фазы -------
!lds R26 , {Значение_синуса_2_фаза}
!inc R26
'----- Исключаем переполнение счетчиков значений синуса, для 252 точек -------
!cpi R26 , &HFC ' десатичное = 252, двоичное = &B11111100,
!BRLO Выход_значение_синуса_2_фаза ' Перейти если меньше
!lds R26 , 1 ' Если равно или больше закидываем в регистр "1"
Выход_значение_синуса_2_фаза:
!sts {Значение_синуса_2_фаза} , R26 ' Пишем значение регистра в переменную
'------ Забираем значение синуса из массива, всего 252 значения -------
Loadadr Значение_синуса(значение_синуса_2_фаза + 1) , Z
!ld R26 , Z ' Забираем текущее значение синуса из массива в регистр
'------ Закидываем полученное значение в регистр таймера -------
!out Ocr0b , R26
'------ Высчитываем выводимое значение синуса для 3 фазы -------
!lds R26 , {Значение_синуса_3_фаза}
!inc R26
'----- Исключаем переполнение счетчиков значений синуса, для 252 точек -------
!cpi R26 , &HFC ' десатичное = 252, двоичное = &B11111100,
!BRLO Выход_значение_синуса_3_фаза ' Перейти если меньше
!lds R26 , 1 ' Если равно или больше закидываем в регистр "1"
Выход_значение_синуса_3_фаза:
!sts {Значение_синуса_3_фаза} , R26 ' Пишем значение регистра в переменную
'------ Забираем значение синуса из массива, всего 252 значения -------
Loadadr Значение_синуса(значение_синуса_3_фаза + 1) , Z
!ld R26 , Z ' Забираем текущее значение синуса из массива в регистр
'------ Закидываем полученное значение в регистр таймера -------
!out Ocr2b , R26
'------ Восстанавливаем ранее сохранённые регистры и SREG -------
!pop R31
!pop R30
!pop R27
!pop R11
!pop R10
!pop R26
!Out Sreg , R26
!pop R26
'------ Выходим из прерывания -------
!reti
nop
'-------------------------------------------------------------------------------
Return
'===============================================================================
'===============================================================================
Обработка_прерывания_ацп:
'-------------------------------------------------------------------------------
nop
'------ Сохраняем используемые регистры и SREG -------
!push R24
!in R24 , sreg
!push r24
!push R25
!push R26
!push R27
'---- Выключаем прерывание от АЦП ----
!in R25 , adcsra ' Читаем значение, время выполнения инструкции - 1 такт
!CBR R25 , &B00001000 ' Сбросить бит в регистре, время выполнения инструкции - 1 такт
!out Adcsra , R25 ' Пишем значение, время выполнения инструкции - 1 такт
'---- Забираем данные из регистров АЦП ----
!in R26 , adcl
!sts {Сырые_данные_ацп(1)} , R26
!in R26 , adch
!sts {Сырые_данные_ацп(2)} , R26
'------ Готовим следующий канал АЦП -------
!in R26 , ADMUX ' Читаем ADMUX
!ANDI R26 , &H07 ' Маской отрезаем лишние биты. Получаем номер канала
!inc R26 ' Делаем ADMUX = ADMUX + 1
!ANDI R26 , &H07 ' Маской отрезаем лишние биты. Получаем следующий номер канала
!cpi R26 , 6 ' Проверяем номер канала
!BRLO Выбор_входа_ацп ' Перейти если меньше
!ldi R26 , 0
Выбор_входа_ацп:
!IN R27 , ADMUX ' Читаем ADMUX
!ANDI R27 , &HF8 ' Маской отрезаем биты номера канала, получаем настройку АЦП
!OR R27 , R26 ' Склеили текущие настройки АЦП c новым значением номера канала, т.е., сделали MUX = MUX + 1
!OUT ADMUX , R27 ' Закидываем полученное значение в регистр АЦП
'------ Забираем готовые данные АЦП в массив -------
!cpi R26 , 0
!BREQ Ацп_0 ' (BREQ) Если равно перейти на метку, время выполнения 2 такта, если не равно 1 такт
!cpi R26 , 1
!BREQ Ацп_1 ' (BREQ) Если равно перейти на метку, время выполнения 2 такта, если не равно 1 такт
!cpi R26 , 2
!BREQ Ацп_2 ' (BREQ) Если равно перейти на метку, время выполнения 2 такта, если не равно 1 такт
!cpi R26 , 3
!BREQ Ацп_3 ' (BREQ) Если равно перейти на метку, время выполнения 2 такта, если не равно 1 такт
!cpi R26 , 4
!BREQ Ацп_4 ' (BREQ) Если равно перейти на метку, время выполнения 2 такта, если не равно 1 такт
!cpi R26 , 5
!BREQ Ацп_5 ' (BREQ) Если равно перейти на метку, время выполнения 2 такта, если не равно 1 такт
Ацп_0:
Данные_ацп(6) = Temp_данные_ацп
!rjmp Запуск_ацп
Ацп_1:
Данные_ацп(1) = Temp_данные_ацп
!rjmp Запуск_ацп
Ацп_2:
Данные_ацп(2) = Temp_данные_ацп
!rjmp Запуск_ацп
Ацп_3:
Данные_ацп(3) = Temp_данные_ацп
!rjmp Запуск_ацп
Ацп_4:
Данные_ацп(4) = Temp_данные_ацп
!rjmp Запуск_ацп
Ацп_5:
Данные_ацп(5) = Temp_данные_ацп
!rjmp Запуск_ацп
'---- Включаем прерывание от АЦП ----
Запуск_ацп:
!in R25 , adcsra ' Читаем значение, время выполнения инструкции - 1 такт
!SBR R25 , &B01001000 ' Установить бит в регистре, время выполнения инструкции - 1 такт
!out Adcsra , R25 ' Пишем значение, время выполнения инструкции - 1 такт
'------ Восстанавливаем ранее сохранённые регистры и SREG -------
!pop R27
!pop R26
!pop R25
!pop R24
!Out Sreg , R24
!pop R24
'------ Выходим из прерывания -------
nop
!reti
'-------------------------------------------------------------------------------
Return
'===============================================================================
'===============================================================================
Таблица_синуса_252: ' 252 значения синусоиды
'-------------------------------------------------------------------------------
Data &H7E , &H82 , &H85 , &H88 , &H8B , &H8E , &H91 , &H94 , &H97 , &H9B
Data &H9E , &HA1 , &HA4 , &HA7 , &HAA , &HAD , &HAF , &HB2 , &HB5 , &HB8
Data &HBB , &HBD , &HC0 , &HC3 , &HC5 , &HC8 , &HCB , &HCD , &HCF , &HD2
Data &HD4 , &HD6 , &HD9 , &HDB , &HDD , &HDF , &HE1 , &HE3 , &HE5 , &HE7
Data &HE8 , &HEA , &HEC , &HED , &HEF , &HF0 , &HF1 , &HF3 , &HF4 , &HF5
Data &HF6 , &HF7 , &HF8 , &HF9 , &HF9 , &HFA , &HFB , &HFB , &HFC , &HFC
Data &HFC , &HFC , &HFC , &HFC , &HFC , &HFC , &HFC , &HFC , &HFC , &HFB
Data &HFB , &HFA , &HF9 , &HF9 , &HF8 , &HF7 , &HF6 , &HF5 , &HF4 , &HF3
Data &HF1 , &HF0 , &HEF , &HED , &HEC , &HEA , &HE8 , &HE7 , &HE5 , &HE3
Data &HE1 , &HDF , &HDD , &HDB , &HD9 , &HD6 , &HD4 , &HD2 , &HCF , &HCD
Data &HCB , &HC8 , &HC5 , &HC3 , &HC0 , &HBD , &HBB , &HB8 , &HB5 , &HB2
Data &HAF , &HAD , &HAA , &HA7 , &HA4 , &HA1 , &H9E , &H9B , &H97 , &H94
Data &H91 , &H8E , &H8B , &H88 , &H85 , &H82 , &H7E , &H7B , &H78 , &H75
Data &H72 , &H6F , &H6C , &H69 , &H66 , &H62 , &H5F , &H5C , &H59 , &H56
Data &H53 , &H50 , &H4E , &H4B , &H48 , &H45 , &H42 , &H40 , &H3D , &H3A
Data &H38 , &H35 , &H32 , &H30 , &H2E , &H2B , &H29 , &H27 , &H24 , &H22
Data &H20 , &H1E , &H1C , &H1A , &H18 , &H16 , &H15 , &H13 , &H11 , &H10
Data &H0E , &H0D , &H0C , &H0A , &H09 , &H08 , &H07 , &H06 , &H05 , &H04
Data &H04 , &H03 , &H02 , &H02 , &H01 , &H01 , &H01 , &H01 , &H01 , &H00
Data &H01 , &H01 , &H01 , &H01 , &H01 , &H02 , &H02 , &H03 , &H04 , &H04
Data &H05 , &H06 , &H07 , &H08 , &H09 , &H0A , &H0C , &H0D , &H0E , &H10
Data &H11 , &H13 , &H15 , &H16 , &H18 , &H1A , &H1C , &H1E , &H20 , &H22
Data &H24 , &H27 , &H29 , &H2B , &H2E , &H30 , &H32 , &H35 , &H38 , &H3A
Data &H3D , &H3F , &H42 , &H45 , &H48 , &H4B , &H4E , &H50 , &H53 , &H56
Data &H59 , &H5C , &H5F , &H62 , &H66 , &H69 , &H6C , &H6F , &H72 , &H75
Data &H78 , &H7B , &H7E
'===============================================================================