Обсуждаем контроллеры компании Atmel.
Ответить

Re: Проблема с fast-ШИМ в AtmelStudio7

Ср ноя 20, 2019 08:38:48

Вот так сделал, проверил - в протеусе шим регулируется.
Спойлер
Код:
/*
 * LightRegulator.c
 *
 * Created: 05.10.2019 20:59:38
 *  Author: Alexander
 */


#define F_CPU 20000000UL
#include <avr/io.h>
#include "buttons-my2.h"
#include "encoder.h"
#include <avr/interrupt.h>
#include <avr/pgmspace.h>

const __flash unsigned int MaxValueSquare[] = {20000,2500,2222,2500,2400,278,204,313,247,
        200,248,278,296,255,222,234,277,247,277,
        250,272,248,246,243,255,266,247,255,250,
        255,260,255,248,251,253,255,255,255,250,
        255,255,255,255,253,252,255,258,255,255,
        255,255,255,253,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255};

const __flash unsigned char LimitValueSquare[] = {2,1,2,4,6,1,1,2,2,
        2,3,4,5,5,5,6,8,8,10,
        10,12,12,13,14,16,18,18,20,21,
        23,25,26,27,29,31,33,35,37,38,
        41,43,45,47,49,51,54,57,59,61,
        64,66,69,71,74,77,80,83,86,89,
        92,95,98,101,104,108,111,114,118,121,
        125,129,132,136,140,143,147,151,155,159,
        163,167,171,176,180,184,189,193,197,202,
207,211,216,221,225,230,235,240,245,250};

const __flash unsigned int MaxValueCube[] = {65535,44444,32776,15625,16000,18520,17490,1953,1372,
        2000,2253,2316,2275,2184,2368,2440,2442,2401,292,
        250,216,188,329,217,255,284,255,228,246,
        222,235,244,278,255,233,257,237,255,253,
        250,261,243,264,258,263,257,260,253,255,
        255,249,255,255,255,252,255,255,255,258,
        255,255,255,255,255,255,255,255,255,255,
        254,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255};

const __flash unsigned char LimitValueCube[] = {1,1,1,1,2,4,6,1,1,
        2,3,4,5,6,8,10,12,14,2,
        2,2,2,4,3,4,5,5,5,6,
        6,7,8,10,10,10,12,12,14,15,
        16,18,18,21,22,24,25,27,28,30,
        32,33,36,38,40,42,45,47,50,53,
        55,58,61,64,67,70,73,77,80,84,
        87,91,95,99,103,108,112,116,121,126,
        131,136,141,146,151,157,162,168,174,180,
186,192,199,205,212,219,226,233,240,247};

const __flash unsigned int MaxValueLog_1[] = {17888,2174,1409,2054,2394,1938,2152,2285,2364,
        2408,2424,2430,2415,2175,2358,2499,2275,2384,2457,
        2259,2429,2240,198,275,255,237,294,274,255,
        298,223,208,292,228,214,281,263,247,232,
        249,234,275,233,268,275,259,244,268,271,
        255,240,257,242,255,266,263,260,255,251,
        247,251,255,255,249,257,255,255,259,255,
        252,259,255,258,257,255,256,253,253,255,
        257,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255};

const __flash unsigned char LimitValueLog_1[] = {4,1,1,2,3,3,4,5,6,
        7,8,9,10,10,12,14,14,16,18,
        18,21,21,2,3,3,3,4,4,4,
        5,4,4,6,5,5,7,7,7,7,
        8,8,10,9,11,12,12,12,14,15,
        15,15,17,17,19,21,22,23,24,25,
        26,28,30,32,33,36,38,40,43,45,
        47,51,53,57,60,63,67,70,74,79,
        84,88,93,99,104,110,117,123,131,138,
146,154,163,173,183,193,204,216,228,241};

const __flash unsigned int MaxValueLog_6[] = {2210,2168,2485,2349,2454,2345,2248,2172,210,
        278,248,297,269,244,279,205,284,262,284,
        264,246,230,246,231,271,255,240,272,257,
        263,268,255,258,261,263,250,252,266,266,
        253,253,263,251,259,257,255,252,249,255,
        258,255,257,253,255,250,257,252,252,252,
        256,255,255,252,255,255,257,255,255,255,
        255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255};

const __flash unsigned char LimitValueLog_6[] = {2,4,7,9,12,14,16,18,2,
        3,3,4,4,4,5,4,6,6,7,
        7,7,7,8,8,10,10,10,12,12,
        13,14,14,15,16,17,17,18,20,21,
        21,22,24,24,26,27,28,29,30,32,
        34,35,37,38,40,41,44,45,47,49,
        52,54,56,58,61,64,67,69,72,75,
        78,81,85,88,92,96,100,104,108,112,
        117,121,126,131,137,142,148,154,160,166,
173,180,187,194,202,210,218,227,236,245};

volatile unsigned char LightLevel = 25; //старший бит сообщает, что уровень изменился
#define MaxLightLevel 100
#define MinLightLevel 0


// Timer 0 overflow interrupt service routine
ISR(TIM0_OVF_vect)
{
        TCNT0=0xB2;  // Reinitialize Timer 0 value
        BUTTON_Scan();
        Encoder_Exe();
        SW_Scan();
}


void SET_Clk_divider_T1 (unsigned int _LimitValue)
{
        if (_LimitValue > 9999)
        {TCCR1B &= 0xF8; TCCR1B |= 0x01;}
        else if (_LimitValue > 999)
        {TCCR1B &= 0xF8; TCCR1B |= 0x02;}
        else {TCCR1B &= 0xF8; TCCR1B |= 0x03;}
}


void SETLightLevel (unsigned char _curve, unsigned char _LightLevel)
{
        unsigned int temp;

        if (_LightLevel == MinLightLevel) {
                TCCR1A &= ~(1<<COM1B1); //отключаем вывод, ШИМ работает
                PORTA &= ~(1<<PORTA5);
        }
        else if (_LightLevel == MaxLightLevel) {
                TCCR1A &= ~(1<<COM1B1); //отключаем вывод, ШИМ работает
                PORTA |= (1<<PORTA5);
        }
        else {
                if ((_LightLevel == (MaxLightLevel-1))||(_LightLevel == (MinLightLevel+1))) TCCR1A |= (1<<COM1B1); //подключаем вывод
                switch (_curve) {
                        case (SQUARE):  {
                                temp = MaxValueSquare[_LightLevel-1];
                                SET_Clk_divider_T1(temp); //установка делителя для счетчика
                                OCR1A = temp;
                                OCR1B = LimitValueSquare[_LightLevel-1];
                        break;}
                        case (CUBE):    {
                                temp = MaxValueCube[_LightLevel-1];
                                SET_Clk_divider_T1(temp); //установка делителя для счетчика
                                OCR1A = temp;
                                OCR1B = LimitValueCube[_LightLevel-1];
                        break;}
                        case (LOG_1):   {
                                temp = MaxValueLog_1[_LightLevel-1];
                                SET_Clk_divider_T1(temp); //установка делителя для счетчика
                                OCR1A = temp;
                                OCR1B = LimitValueLog_1[_LightLevel-1];
                        break;}
                        case (LOG_6):   {
                                temp = MaxValueLog_6[_LightLevel-1];
                                SET_Clk_divider_T1(temp); //установка делителя для счетчика
                                OCR1A = temp;
                                OCR1B = LimitValueLog_6[_LightLevel-1];
                        break;}
                        default:    {
                                OCR1A = MaxLightLevel;
                        OCR1B = _LightLevel;}
                };
        }
}


int main(void)
{


        // Crystal Oscillator division factor: 1
        //#pragma optsize-
        CLKPR=(1<<CLKPCE);
        CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
        #ifdef _OPTIMIZE_SIZE_
        //#pragma optsize+
        #endif

        // Input/Output Ports initialization
        {
                // Port A initialization
                // Function: Bit7=In Bit6=In Bit5=Out Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
                DDRA=(0<<DDA7) | (0<<DDA6) | (1<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
                // State: Bit7=T Bit6=T Bit5=0 Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T
                PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

                // Port B initialization
                // Function: Bit3=In Bit2=In Bit1=In Bit0=In
                DDRB=(0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
                // State: Bit3=T Bit2=T Bit1=T Bit0=T
                PORTB=(0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);
        }

        // Timer/Counter 0 initialization
        {
                // Clock source: System Clock
                // Clock value: 78.125 kHz
                // Mode: Normal top=0xFF
                // OC0A output: Disconnected
                // OC0B output: Disconnected
                // Timer Period: 0.9984 ms
                TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (0<<WGM01) | (0<<WGM00);
                TCCR0B=(0<<WGM02) | (1<<CS02) | (0<<CS01) | (0<<CS00);
                TCNT0=0xB2;
                OCR0A=0x00;
                OCR0B=0x00;
        }

        // Timer/Counter 1 initialization
        {
                // Clock source: System Clock
                // Clock value: 20000.000 kHz
                // Mode: Fast PWM top=OCR1A
                // OC1A output: Disconnected
                // OC1B output: Non-Inverted PWM
                // Noise Canceler: Off
                // Input Capture on Falling Edge
                // Timer Period: 0.0128 ms
                // Output Pulse(s):
                // OC1B Period: 0.0128 ms Width: 0.55216 us
                // Timer1 Overflow Interrupt: Off
                // Input Capture Interrupt: Off
                // Compare A Match Interrupt: Off
                // Compare B Match Interrupt: Off
                TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (1<<COM1B1) | (0<<COM1B0) | (1<<WGM11) | (1<<WGM10);
                TCCR1B=(0<<ICNC1) | (0<<ICES1) | (1<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
                TCNT1=0x0000;
                ICR1=0x0000;
                OCR1A=0x00FF;
                OCR1B=0x000B;
        }

        // Timer/Counter 0 Interrupt(s) initialization
        TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (1<<TOIE0);

        // Timer/Counter 1 Interrupt(s) initialization
        TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1);

        // External Interrupt(s) initialization
        {
                // INT0: Off
                // Interrupt on any change on pins PCINT0-7: Off
                // Interrupt on any change on pins PCINT8-11: Off
                MCUCR=(0<<ISC01) | (0<<ISC00);
                GIMSK=(0<<INT0) | (0<<PCIE1) | (0<<PCIE0);
        }

        // USI initialization
        {
                // Mode: Disabled
                // Clock source: Register & Counter=no clk.
                // USI Counter Overflow Interrupt: Off
                USICR=(0<<USISIE) | (0<<USIOIE) | (0<<USIWM1) | (0<<USIWM0) | (0<<USICS1) | (0<<USICS0) | (0<<USICLK) | (0<<USITC);
        }

        // Analog Comparator initialization
        {
                // Analog Comparator: Off
                // The Analog Comparator's positive input is
                // connected to the AIN0 pin
                // The Analog Comparator's negative input is
                // connected to the AIN1 pin
                ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
                ADCSRB=(0<<ACME);
                // Digital input buffer on AIN0: On
                // Digital input buffer on AIN1: On
                DIDR0=(0<<ADC1D) | (0<<ADC2D);
        }

        // ADC initialization
        {
                // ADC disabled
                ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);
        }

        Encoder_Init();
        LightLevel |= 0x80;
        sei();
        while (1)
        {
                switch (ScanKey) {
                        case (KEY_UP):   {ScanKey = KEY_NULL;
                                if (LightLevel > (MaxLightLevel-1))  LightLevel = MaxLightLevel;
                                else {LightLevel++; LightLevel |= 0x80;}
                        break;}
                        case (KEY_DOWN): {ScanKey = KEY_NULL;
                                if (LightLevel == MinLightLevel)  LightLevel = MinLightLevel;
                                else {LightLevel--; LightLevel |= 0x80;}
                        break;}
                };
                if (LightLevel & 0x80) {
                        LightLevel &= ~(0x80);
                        SETLightLevel (Curve, LightLevel);
                }


        }
}


HEX:
Спойлер
Код:
:1000000062C27CC27BC27AC279C278C277C276C22F
:1000100075C274C273C2DCC271C270C26FC26EC2DA
:100020006DC2020407090C0E10120203030404043B
:10003000050406060707070708080A0A0A0C0C0D3C
:100040000E0E0F101111121415151618181A1B1C6C
:100050001D1E202223252628292C2D2F3134363809
:100060003A3D404345484B4E5155585C6064686C7E
:100070007075797E83898E949AA0A6ADB4BBC2CAEE
:10008000D2DAE3ECF5A2087808B5092D099609291A
:1000900009C8087C08D2001601F80029010D01F4F6
:1000A000001701CD001C0106011C010801F600E645
:1000B00000F600E7000F01FF00F00010010101074A
:1000C000010C01FF00020105010701FA00FC000A12
:1000D000010A01FD00FD000701FB0003010101FF12
:1000E00000FC00F900FF000201FF000101FD00FF1C
:1000F00000FA000101FC00FC00FC000001FF00FF11
:1001000000FC00FF00FF000101FF00FF00FF00FFF7
:1001100000FF00FF00FF00FF00FF00FF00FF00FFE7
:1001200000FF00FF00FF00FF00FF00FF00FF00FFD7
:1001300000FF00FF00FF00FF00FF00FF00FF00FFC7
:1001400000FF00FF00FF00FF00FF000401010203A9
:10015000030405060708090A0A0C0E0E10121215F0
:100160001502030303040404050404060505070738
:10017000070708080A090B0C0C0C0E0F0F0F1111C2
:100180001315161718191A1C1E20212426282B2D8A
:100190002F3335393C3F43464A4F54585D63686EB0
:1001A000757B838A929AA3ADB7C1CCD8E4F1E045C0
:1001B0007E08810506085A0992076808ED083C097F
:1001C000680978097E096F097F083609C309E308C1
:1001D00050099909D3087D09C008C6001301FF0022
:1001E000ED0026011201FF002A01DF00D0002401EA
:1001F000E400D60019010701F700E800F900EA0061
:100200001301E9000C0113010301F4000C010F01BB
:10021000FF00F0000101F200FF000A0107010401E4
:10022000FF00FB00F700FB00FF00FF00F9000101E9
:10023000FF00FF000301FF00FC000301FF000201BB
:100240000101FF000001FD00FD00FF000101FF00B2
:10025000FF00FF00FF00FF00FF00FF00FF00FF00A6
:10026000FF00FF00FF00FF00FF00FF00FF00FF0096
:10027000FF00FF0001010101020406010102030465
:100280000506080A0C0E0202020204030405050515
:10029000060607080A0A0A0C0C0E0F101212151691
:1002A00018191B1C1E20212426282A2D2F323537F1
:1002B0003A3D404346494D5054575B5F63676C700D
:1002C00074797E83888D92979DA2A8AEB4BAC0C778
:1002D000CDD4DBE2E9F0F7FFFF9CAD0880093D805B
:1002E0003E58485244A1075C05D007CD080C09E3ED
:1002F000088808400988098A0961092401FA00D898
:1003000000BC004901D900FF001C01FF00E400F619
:1003100000DE00EB00F4001601FF00E9000101ED32
:1003200000FF00FD00FA000501F3000801020107CB
:100330000101010401FD00FF00FF00F900FF00FFC3
:1003400000FF00FC00FF00FF00FF000201FF00FFB4
:1003500000FF00FF00FF00FF00FF00FF00FF00FFA5
:1003600000FE00FF00FF00FF00FF00FF00FF00FF96
:1003700000FF00FF00FF00FF00FF00FF00FF00FF85
:1003800000FF00FF00FF00FF00FF00FF00FF00FF75
:1003900000FF00FF00FF00FF00FF00FF000201025E
:1003A0000406010102020203040505050608080A05
:1003B0000A0C0C0D0E101212141517191A1B1D1F02
:1003C00021232526292B2D2F313336393B3D404221
:1003D00045474A4D505356595C5F6265686C6F7271
:1003E00076797D8184888C8F93979B9FA3A7ABB0F0
:1003F000B4B8BDC1C5CACFD3D8DDE1E6EBF0F5FA9C
:10040000204EC409AE08C40960091601CC003901A8
:10041000F700C800F80016012801FF00DE00EA001E
:100420001501F7001501FA001001F800F600F300BD
:10043000FF000A01F700FF00FA00FF000401FF00BF
:10044000F800FB00FD00FF00FF00FF00FA00FF00C6
:10045000FF00FF00FF00FD00FC00FF000201FF00A5
:10046000FF00FF00FF00FF00FD00FF00FF00FF0096
:10047000FF00FF00FF00FF00FF00FF00FF00FF0084
:10048000FF00FF00FF00FF00FF00FF00FF00FF0074
:10049000FF00FF00FF00FF00FF00FF00FF00FF0064
:1004A000FF00FF00FF00FF00FF00FF00FF00FF0054
:1004B000FF00FF00FF00FF00FF00FF00FF00FF0044
:1004C000FF00FF00FF0011241FBECFE5D1E0DEBF1B
:1004D000CDBF10E0A0E6B0E0E0E5F8E002C0059096
:1004E0000D92A436B107D9F720E0A4E6B0E001C030
:1004F0001D92A936B207E1F73CD1A8C181CDCE9BB0
:1005000004C0CC9904C082E003C081E001C080E057
:10051000882391F0909165009B3F30F096E990938D
:1005200065008093660008959F3011F48093660003
:100530009F5F909365000895109265000895C89B91
:1005400008C0C99B08C0CA9B08C0CB9908C084E0FA
:1005500007C081E005C082E003C083E001C085E000
:100560009091620089130BC090916400903118F053
:100570008093610008959F5F9093640008951092A6
:1005800064008093620008951092680010926700E2
:100590000895B29B02C080E001C081E0CF9B8260E1
:1005A00090916800891799F0933069F42091670061
:1005B000821749F0823021F422E02093660003C0C4
:1005C00021E020936600909367008093680008956F
:1005D0001F920F920FB60F9211242F933F934F93B8
:1005E0005F936F937F938F939F93AF93BF93EF939B
:1005F000FF9382EB82BF83DFCCDFA1DFFF91EF911E
:10060000BF91AF919F918F917F916F915F914F912A
:100610003F912F910F900FBE0F901F901895803132
:1006200027E2920738F08EB5887F8EBD8EB5816047
:100630008EBD0895883E934038F08EB5887F8EBD7C
:100640008EB582608EBD08958EB5887F8EBD8EB5C5
:1006500083608EBD08950F931F93CF93DF93611135
:1006600007C08FB58F7D8FBD8BB38F7D8BBB7CC05B
:10067000643639F48FB58F7D8FBD8BB380628BBBB1
:1006800073C0633611F0613019F49FB590629FBD5D
:10069000C62F823001F118F4813039F05EC083300A
:1006A00081F1843009F443C058C0C62FD0E02197AF
:1006B000FE01EE0FFF1FE050FC4F05911591C801A0
:1006C000AEDF1BBD0ABDFE01E356FC4F849190E0F6
:1006D00099BD88BD49C0C62FD0E02197FE01EE0F1D
:1006E000FF1FE952FD4F05911591C80198DF1BBD11
:1006F0000ABDFE01EC58FD4F849190E099BD88BD84
:1007000033C0C62FD0E02197FE01EE0FFF1FE25548
:10071000FE4F05911591C80182DF1BBD0ABDFE0188
:10072000E55BFE4F849190E099BD88BD1DC0C62F4A
:10073000D0E02197FE01EE0FFF1FEB57FF4F059111
:100740001591C8016CDF1BBD0ABDFE01EE5DFF4FB8
:10075000849190E099BD88BD07C084E690E09BBD80
:100760008ABDD0E0D9BDC8BDDF91CF911F910F9157
:10077000089580E886BD16BC90E29ABB1BBA17BAF2
:1007800018BA10BE94E093BF92EB92BF16BE1CBE87
:1007900093E29FBD99E19EBD1DBC1CBC15BC14BC61
:1007A0002FEF30E03BBD2ABD2BE030E039BD28BD46
:1007B00091E099BF1CB815BE1BBE1DB888B913B80F
:1007C00011B816B8E1DE8091600080688093600007
:1007D0007894809166008130B9F0823041F51092B2
:1007E000660080916000843620F084E6809360008B
:1007F0001EC0809160008F5F8093600080916000D8
:1008000080688093600013C0109266008091600041
:10081000811103C0109260000AC080916000815075
:100820008093600080916000806880936000809178
:100830006000882374F6809160008F778093600059
:10084000609160008091610006DFC3CFF894FFCF14
:040850001901010089
:00000001FF


Куда удобнее, чем возня с pgm_read_word().

Re: Проблема с fast-ШИМ в AtmelStudio7

Ср ноя 20, 2019 19:26:08

Исправил я своё упущение в AS - сделал присваивание через pgm_read_word(& ). И ШИМ заработал в Протеусе!!! :)) УРА!
NStorm, опробовал и Ваше предложение. Действительно удобнее! :) Супер!
Выражаю благодарность всем откликнувшимся! :beer: :beer: :beer: Большое спасибо вам! :beer:
Ответить