Forum: Mikrocontroller und Digitale Elektronik AT91sam7s256 dynamic PWM


von Matze M. (Firma: Student Informatik) (maze)


Lesenswert?

Hallo an die Experten,

ich möchte ein dynamisches pwm signal erzeugen was schon funktioniert 
aber mein Problem ist das ich auch sagen möchte ob es positive ist oder 
negative in laufe der zeit ist. Ich habe dazu ein Interrupt routine
PWM_hander();
die Periodenzeit und die Cycletime updated, aber wenn ich sagen will das 
signal soll jetzt positive oder negative sein wird dies nicht 
aktualisiert??
mein Programm sieht so aus:
1
void PWM_init( void )
2
{
3
    unsigned int Tmp;
4
    
5
    g_PeriodTime                   = DEFAULT_PERIOD;
6
    g_ListOfDutyCycles[0]          = DEFAULT_PULSE;
7
    g_NRofDefPulse                 = DEFAULT_NR_OF_DEF_PULSE;
8
    g_CountNextPulseNR             = 0;
9
10
    // Enable User Reset and set its minimal assertion to 960 us
11
    //   AT91C_RSTC_URSTIEN ==  AT91C_SYSC_URSTIEN
12
    //AT91C_BASE_RSTC->RSTC_RMR = AT91C_RSTC_URSTIEN | (0x4<<8) | (unsigned int)(0xA5<<24);
13
14
15
    // First, enable the clock of the PIO
16
    //AT91C_ID_PIOA   ((unsigned int)  2) // Parallel IO Controller
17
    AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ) ;
18
19
    // then, we configure the PIO Lines corresponding to LED1 to LED4
20
    // to be outputs. No need to set these pins to be driven by the PIO because it is GPIO pins only.
21
    ////////////////////////////////////////////////AT91F_PIO_CfgOutput( AT91C_BASE_PIOA, LED_MASK ) ;
22
23
    // Clear the output (LEDs on)
24
    ////////////////////////////////////////////////AT91F_PIO_SetOutput( AT91C_BASE_PIOA, 0 ) ;
25
26
    // now initializes PWM
27
28
    // Enabling a PWM output through the PIO, peripheral A, PA0
29
    AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, AT91C_PA0_PWM0, 0);
30
31
    // Configure PMC by enabling PWM clock
32
    AT91F_PWMC_CfgPMC ();//LED1 on
33
    AT91F_PWMC_StopChannel(AT91C_BASE_PWMC,AT91C_PWMC_CHID0);
34
35
    // Set the Clock A divider
36
    AT91C_BASE_PWMC->PWMC_MR = (( PWM_SCALER << 8 ) | PWM0_DIVIDER);
37
38
    // Set the Clock
39
    //         - divider clock A
40
    //         - CALG=0 Left aligned
41
    //         - CPOL=1 sart at High level (0 inverse output)
42
    //         - CPD=0 update the dute cycle
43
    AT91C_BASE_PWMC_CH0->PWMC_CMR = AT91C_PWMC_CPRE_MCKA | CPD_OFF | CPOL_ON | CALG_OFF ; //LED1 Aus???
44
45
    // Set the Period register (sample size bit fied )
46
    AT91C_BASE_PWMC_CH0->PWMC_CPRDR = g_PeriodTime;//Period;
47
    // Set the duty cycle register (output value)
48
    AT91C_BASE_PWMC_CH0->PWMC_CDTYR = g_ListOfDutyCycles[0];//Pulse0;
49
    // Initialise the Update register write only
50
    AT91C_BASE_PWMC_CH0->PWMC_CUPDR = DEFAULT_NEXT_PULSE;//Pulse1;
51
52
53
    // Now start the PWM channel
54
    AT91F_PWMC_StartChannel(AT91C_BASE_PWMC,AT91C_PWMC_CHID0);//LED1 Blinking
55
56
57
    /* Open PWM interrupt*/
58
    //AT91SAM64.h neue definitions schreibweise
59
//    #define AT91C_AIC_SRCTYPE     ((unsigned int) 0x3 <<  5) // (AIC) Interrupt Source Type
60
//    #define   AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE  ((unsigned int) 0x0 <<  5) // (AIC) Internal Sources Code Label Level Sensitive
61
    
62
    /*AT91SAM256.h neue definitions schreibweise*/
63
//    #define AT91C_AIC_SRCTYPE     ((unsigned int) 0x3 <<  5) // (AIC) Interrupt Source Type
64
//    #define   AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL       ((unsigned int) 0x0 <<  5) // (AIC) Internal Sources Code Label High-level Sensitive
65
    AT91F_AIC_ConfigureIt( AT91C_BASE_AIC,
66
                          AT91C_ID_PWMC, 
67
                          PWM_INTERRUPT_LEVEL,
68
                          AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, 
69
                          PWM_handler);   
70
    
71
    AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_PWMC);
72
73
    // Enable IRQ
74
    AT91F_PWMC_InterruptEnable(AT91C_BASE_PWMC,AT91C_PWMC_CHID0);
75
    Tmp = AT91C_BASE_PWMC->PWMC_ISR;
76
    Tmp = Tmp;
77
}
78
void PWM_handler(void)
79
{
80
  unsigned int Tmp;
81
  // Hand check the interrupt
82
  Tmp = AT91C_BASE_PWMC->PWMC_ISR;
83
  Tmp = Tmp;
84
85
   //Initialise the Update register write only
86
  if(g_ListOfDutyCycles[ g_CountNextPulseNR]!=0)
87
  {
88
    if(g_CountNextPulseNR<g_NRofDefPulse)// aktuelle periode < anzahl der perioden
89
    {
90
  
91
          AT91C_BASE_PWMC_CH0->PWMC_CUPDR =g_ListOfDutyCycles[ g_CountNextPulseNR++ ];
92
          
93
          if(g_CountNextPulseNR >= g_NRofDefPulse)// Counter overflow set back 
94
             g_CountNextPulseNR=0;
95
    }
96
    else
97
    {
98
        g_CountNextPulseNR=0;//rücksetzten des counters
99
    }
100
  }
101
          
102
  // Set the Period register (sample size bit fied )
103
  AT91C_BASE_PWMC_CH0->PWMC_CPRDR =g_PeriodTime;
104
105
  irqCntr++;
106
  
107
}
108
109
void PWM_pos(){
110
        AT91C_BASE_PWMC_CH0->PWMC_CMR = AT91C_PWMC_CPRE_MCKA | CPD_OFF| CPOL_ON| CALG_OFF;
111
}
112
void PWM_neg(){
113
        AT91C_BASE_PWMC_CH0->PWMC_CMR = AT91C_PWMC_CPRE_MCKA | CPD_OFF| CPOL_OFF| CALG_OFF;
114
}
PWM_pos()und  PWM_neg()
haben leider keine aus wirkung auf das pwm signal wis jemand warum??

auch wenn ich das singnal vorher anhalte in PWM_neg oder PWM_pos, mit
1
 AT91F_PWMC_StopChannel(AT91C_BASE_PWMC,AT91C_PWMC_CHID0);
2
3
 AT91F_PWMC_StartChannel(AT91C_BASE_PWMC,AT91C_PWMC_CHID0);
hat das keine auswirkungen!!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.