Sida 1 av 2
PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 19:15:56
av Erik M
Efter diverse strul och besvär har jag fått någorlunda ordning på PWM med PIC12F683. Fortfarande grundligt irriterad på hur de åtta MSB och två LSB inte sitter ihop på något vettigt vis. Det är riktigt absurt vad som krävs för att få tom respektive full Duty Cycle. Nå, det är som det är med det. Får se vad för påhitt som går att trassla med vid byte till PIC12F1572...
Vad som finns att arbeta med är följande register och inställningar:
Screenshot_2016-07-04-18-38-53.jpg
Varje register och inställning är nog gott beskriven, vilket dock inte innebär att det går förstå spontant eller intuitivt hur allting hänger ihop.
Vad jag tror jag kommit fram till stannar vid att man kan välja mellan att signalen läses internt eller går ut till pinne.
Det vill säga...
OE: PWM Output Enable bit 1 = PWM output pin enabled 0 = PWM output pin disabled
Samt ett antal olika sätt rotera, starta, stoppa, interagera etc. Just nu information om än en intressant.
Hur alla dessa register sedan skall kombineras för att göra något man önskar - det är väl förborgade hemligheter. Fram tills dess att de inte är det - längre.
Men i detta nu är de just dylika hemligheter, för mig.
Hur går man tillväga för att skapa en standard PWM (PWMxMODE = 00) här?
Låt säga att Fosc är 16MHz, Period önskas vara 5us och en Duty Cycle om 25%, vad sätter man till vad?
Vi vet att:
Period = (PWMxPR + 1) * Prescale / PWMxCLK
Duty Cycle = (PWMxDC - PWMxPH) / (PWMxPR + 1)
Dock tas i dessa beräkningar ingen hänsyn till Fosc, vilket gör dem besynnerliga.
Och omöjliga att använda.
Eller ska det förstås att PWMxCLK = 1 / Fosc, i detta fall 62.5ns?
Vilket skulle ge Period * PWMxCLK = (5us * 62.5ns / Prescale) - 1 = PWMxPR
Och sedan är det alla övriga register och inställningar...
Hur får man ihop något så enkelt som ovan?

Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 19:22:35
av sodjan
Om jag hinner kan jag ta en koll senare. Jag misstänker
att man kan "torrsimma" och testa i MPSIM...
Men jag *gissar* att det bara är att läsa och ta en sak i taget...

Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:04:45
av Erik M
Det är för många olika saker som inte är beskrivna gentemot varandra, mer än principiellt.
Hur de olika avgränsningar fungerar går
nästan att utläsa ur exempelvis FIGURE 22-4:STANDARD PWM MODE TIMING DIAGRAM.
Men det är just detta nästan som det blir för många.
Hade det varit med ett enda exempel skulle mycket varit vunnet.
Skulle uppskattas stort, Janne.
Att leta efter lämpliga snuttar kod på nätet är typ hopplöst.
Det mesta är skrivet i C, och inte ASM. Så dåligt med hjälp där.
Visst, det går säkert lösa ut, men lika gärna att det blir baklänges och fel.
Och jag har försökt ta det ett steg i taget.
Utan de första pusselbitarna på plats går det hopplöst långsamt att hitta de mönster som krävs för att få ihop det. Och det är för lätt att missa något ynka litet steg, som i sig sedan omöjliggör alltihop.
Vi har väl alla slitit vårt hår över det där lilla kommatecknet som är omöjligt finna ut att eller var det fattas... Om man sedan inte vet att det ens skall vara där... Då blir det besvärligt.
Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:09:45
av sodjan
Att "översätta" C till motsvarande ASM bör inte vara något problem,
så länge som exemplen bara använder direkta register, inga "libbar".
Har du hitta något alls till dessa nyare modeller?
Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:13:22
av Erik M
Inte ännu, jag läser och begrundar databladet än.
Fångar en liten ynka bit i taget och försöker ge den ett sammanhang.
Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:15:10
av sodjan
Alltså:
> Det mesta är skrivet i C...
Som vad t.ex.? Vad är det du syftar på?
Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:22:56
av Erik M
Den kod man hittar att gå vidare från är oftast skriven i C.
Jag skulle föredra ASM.
Hm... Rotar just runt borta hos MicroChip - är deras MPLAB Code Configurator hjälpsam?
Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:29:00
av TomasL
Nej, den är avsedd för C och MPLABX för att konfigurera bl.a. de olika periferienheterna och lite annat.
The MPLAB Code Configurator is a free graphical programming environment that generates seamless, easy to understand C code that is inserted into your project. Using an intuitive interface it enables and configures a rich set of peripherals and functions. It is integrated into MPLAB X IDE to provide a powerful and easy to use development platform.
Varför inte gå över till C istället, fasiken så mycket bekvämare.
Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:39:09
av sodjan
MCC genererar C kod, men det kan ju som jag sa vara till hjälp ändå.
Det är ju samma register oavsett om man kör C eller ASM, bara att
göra samma sak i ASM...
Testade att sätta up PWM1 i MCC och fick nedanstående.
Kört med 32 MHz, Standard-PWM, clock-source FOSC, Independent-run,
period 1000 ns, Phase 0, offset 62.5 ns (default), Duty 50%.
Jag tycker att koden är väldigt tydlig och ren och bör inte vara något
problem att överföra till ASM. Man får förutom en grundinställning enligt
vad man valde i MCC, även färdiga funktioner för att ändra inställningar.
Ser himla trevligt ut, måste jag säga...
Kod: Markera allt
/**
PWM1 Generated Driver File
@Company
Microchip Technology Inc.
@File Name
pwm1.c
@Summary
This is the generated driver implementation file for the PWM1 driver using MPLAB(c) Code Configurator
@Description
This header file provides implementations for driver APIs for PWM1.
Generation Information :
Product Revision : MPLAB(c) Code Configurator - 3.15.0
Device : PIC12F1572
Driver Version : 1.0
The generated drivers are tested against the following:
Compiler : XC8 1.35
MPLAB : MPLAB X 3.20
*/
/*
(c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this
software and any derivatives exclusively with Microchip products.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
TERMS.
*/
/**
Section: Included Files
*/
#include <xc.h>
#include "pwm1.h"
/**
Section: PWM1 APIs
*/
void PWM1_Initialize(void)
{
// set the PWM1 to the options selected in the User Interface
//PHIE disabled; DCIE disabled; OFIE disabled; PRIE disabled;
PWM1INTE = 0x00;
//PHIF cleared; OFIF cleared; DCIF cleared; PRIF cleared;
PWM1INTF = 0x00;
//PS No_Prescalar; CS FOSC;
PWM1CLKCON = 0x00;
//LDS reserved; LDT disabled; LDA do_not_load;
PWM1LDCON = 0x00;
//OFM independent_run; OFS reserved; OFO match_incrementing;
PWM1OFCON = 0x00;
//PWM1PHH 0;
PWM1PHH = 0x00;
//PWM1PHL 0;
PWM1PHL = 0x00;
//PWM1DCH 0;
PWM1DCH = 0x00;
//PWM1DCL 16;
PWM1DCL = 0x10;
//PWM1PRH 0;
PWM1PRH = 0x00;
//PWM1PRL 31;
PWM1PRL = 0x1F;
//PWM1OFH 0;
PWM1OFH = 0x00;
//PWM1OFL 1;
PWM1OFL = 0x01;
//PWM1TMRH 0;
PWM1TMRH = 0x00;
//PWM1TMRL 0;
PWM1TMRL = 0x00;
//MODE standard_PWM; POL active_hi; OE enabled; EN enabled;
PWM1CON = 0xC0;
}
void PWM1_Start(void)
{
PWM1CONbits.EN = 1;
}
void PWM1_Stop(void)
{
PWM1CONbits.EN = 0;
}
bool PWM1_CheckOutputStatus(void)
{
return (PWM1CONbits.OUT);
}
void PWM1_LoadBufferSet(void)
{
PWM1LDCONbits.LDA = 1;
}
void PWM1_PhaseSet(uint16_t phaseCount)
{
PWM1PHH = (phaseCount>>8); //writing 8 MSBs to PWMPHH register
PWM1PHL = (phaseCount); //writing 8 LSBs to PWMPHL register
}
void PWM1_DutyCycleSet(uint16_t dutyCycleCount)
{
PWM1DCH = (dutyCycleCount>>8); //writing 8 MSBs to PWMDCH register
PWM1DCL = (dutyCycleCount); //writing 8 LSBs to PWMDCL register
}
void PWM1_PeriodSet(uint16_t periodCount)
{
PWM1PRH = (periodCount>>8); //writing 8 MSBs to PWMPRH register
PWM1PRL = (periodCount); //writing 8 LSBs to PWMPRL register
}
void PWM1_OffsetSet(uint16_t offsetCount)
{
PWM1OFH = (offsetCount>>8); //writing 8 MSBs to PWMOFH register
PWM1OFL = (offsetCount); //writing 8 LSBs to PWMOFL register
}
uint16_t PWM1_TimerCountGet(void)
{
return ((PWM1TMRH<<8) | PWM1TMRL);
}
bool PWM1_IsOffsetMatchOccured(void)
{
return (PWM1INTFbits.OFIF);
}
bool PWM1_IsPhaseMatchOccured(void)
{
return (PWM1INTFbits.PHIF);
}
bool PWM1_IsDutyCycleMatchOccured(void)
{
return (PWM1INTFbits.DCIF);
}
bool PWM1_IsPeriodMatchOccured(void)
{
return (PWM1INTFbits.PRIF);
}
/**
End of File
*/
Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:49:33
av Erik M
TomasL ~ Verkar ju perfekt för att generera SFR-kod.
Någonstans på vägen från C över till HEX månne man kan se hur det ser ut i ASM...?
Redan i MPLAB kan man ju generera config word.
Egentligen märkligt, eller jag som inte grävt tillräckligt för att hitta det, att MPLAB inte ger samma möjlighet som exempelvis FlowCode vad gäller att mer eller mindre grafiskt kunna ange var man vill ha en funktion i funktion, direkt på raden i koden.
Suveränt Janne, stort tack.
Och det är som du säger - klart och tydligt vad som skall ställas in till vad.
Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:50:23
av sodjan
Totalt skapas 6 filer, 3 C-filer och 3 h-filer.
C filerna är för grundinställningar (som inte har direkt med PWM att göra),
pin-konfiguration (delvis styrs av PWM definitioner) samt PWM filen ovan.
H-filen för PWM innehåller också lite mer dokumentation för de olika
hjälp-funktionerna.
(Exempel koden till PWM_Stop() har ett litet fel...

)
Kod: Markera allt
/**
PWM1 Generated Driver API Header File
@Company
Microchip Technology Inc.
@File Name
pwm1.h
@Summary
This is the generated header file for the PWM1 driver using MPLAB(c) Code Configurator
@Description
This header file provides APIs for driver for PWM1.
Generation Information :
Product Revision : MPLAB(c) Code Configurator - 3.15.0
Device : PIC12F1572
Driver Version : 1.0
The generated drivers are tested against the following:
Compiler : XC8 1.35
MPLAB : MPLAB X 3.20
*/
/*
(c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this
software and any derivatives exclusively with Microchip products.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
TERMS.
*/
#ifndef _PWM1_H
#define _PWM1_H
/**
Section: Included Files
*/
#include <xc.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus // Provide C++ Compatibility
extern "C" {
#endif
/**
Section: PWM Module APIs
*/
/**
@Summary
Initializes the PWM1
@Description
This routine initializes the Initializes the PWM1.
This routine must be called before any other PWM routine is called.
This routine should only be called once during system initialization.
@Preconditions
None
@Param
None
@Returns
None
@Comment
@Example
<code>
</code>
*/
void PWM1_Initialize(void);
/**
@Summary
This function starts the PWM1.
@Description
This function starts the PWM1 operation.
This function must be called after the initialization of PWM1.
@Preconditions
Initialize the PWM1 before calling this function.
@Param
None
@Returns
None
@Example
<code>
// Initialize PWM1 module
// Start PWM1
PWM1_Start();
// Do something else...
</code>
*/
void PWM1_Start(void);
/**
@Summary
This function stops the PWM1.
@Description
This function stops the PWM1 operation.
This function must be called after the start of PWM1.
@Preconditions
Initialize the PWM1 before calling this function.
@Param
None
@Returns
None
@Example
<code>
// Initialize PWM1 module
// Start PWM1
PWM1_StartTimer();
// Do something else...
// Stop PWM1;
PWM1_Stop();
</code>
*/
void PWM1_Stop(void);
/**
@Summary
This function used to check output status of PWM1.
@Description
Check output status of PWM1 as High or Low.
@Preconditions
Start the PWM1 before calling this function.
@Param
None
@Returns
true - Output High.
false - Output Low.
@Example
<code>
</code>
*/
bool PWM1_CheckOutputStatus(void);
/**
@Summary
This function is used to load buffer of PWM1 at the end of period.
@Description
load buffer of PWM1 at the end of period.
@Preconditions
Initialize the PWM1 before calling this function.
@Param
None
@Returns
None
@Example
<code>
</code>
*/
void PWM1_LoadBufferSet(void);
/**
@Summary
Load required 16 bit phase count
@Description
Set the expected phase count
@Preconditions
None
@Param
Pass 16 bit phase count
@Returns
None
@Example
<code>
</code>
*/
void PWM1_PhaseSet(uint16_t phaseCount);
/**
@Summary
Load required 16 bit Duty Cycle
@Description
Set the expected Duty Cycle
@Preconditions
None
@Param
Pass 16 bit Duty Cycle
@Returns
None
@Example
<code>
</code>
*/
void PWM1_DutyCycleSet(uint16_t dutyCycleCount);
/**
@Summary
Load required 16 bit Period
@Description
Set the expected Period
@Preconditions
None
@Param
Pass 16 bit Period
@Returns
None
@Example
<code>
</code>
*/
void PWM1_PeriodSet(uint16_t periodCount);
/**
@Summary
Load required 16 bit Offset
@Description
Set the expected Offset
@Preconditions
None
@Param
Pass 16 bit Offset
@Returns
None
@Example
<code>
</code>
*/
void PWM1_OffsetSet(uint16_t offsetCount);
/**
@Summary
Read measured Timer count
@Description
Read the measured Timer count
*
@Preconditions
None
@Param
None
@Returns
Return 16 bit Timer count
@Example
<code>
</code>
*/
uint16_t PWM1_TimerCountGet(void);
/**
@Summary
Returns status of Offset interrupt flag bit (OFIF ).
@Description
When PWMTMR = PWMOF value offset flag sets.
@Preconditions
None
@Param
None
@Returns
true - PWMTMR >= PWMOF value
false - PWMTMR < PWMOF value
@Example
<code>
</code>
*/
bool PWM1_IsOffsetMatchOccured(void);
/**
@Summary
Returns status of Phase interrupt flag bit (PHIF ).
@Description
When PWMTMR = PWMPH value, Phase flag sets.
@Preconditions
None
@Param
None
@Returns
true - PWMTMR count is >= PWMPH value
false - PWMTMR count is < PWMPH value
@Example
<code>
</code>
*/
bool PWM1_IsPhaseMatchOccured(void);
/**
@Summary
Returns status of DutyCycle interrupt flag bit (DCIF ).
@Description
When PWMTMR = PWMDC value DutyCycle flag sets.
@Preconditions
None
@Param
None
@Returns
true - PWMTMR count is >= PWMDC value
false - PWMTMR count is < PWMDC value
@Example
<code>
</code>
*/
bool PWM1_IsDutyCycleMatchOccured(void);
/**
@Summary
Returns status of Period interrupt flag bit (PRIF ).
@Description
When PWMTMR = PWMPR value offset flag sets.
@Preconditions
None
@Param
None
@Returns
true - PWMTMR count is >= PWMPR value
false - PWMTMR count is < PWMPR value
@Example
<code>
</code>
*/
bool PWM1_IsPeriodMatchOccured(void);
#endif /* PWM1_H */
/**
End of File
*/
Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:54:36
av sodjan
En sak att notera är att det är väldigt enkelt att installera plugins som MCC.
Det görs inne i MPLABX via menyn Tools->Plugins. Sen "Available Plugins"
och markera MCC. Nerladdning och installation sker av MLPABX och det
blir tillgängligt direkt utan omstart.
Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:56:23
av Erik M
PWM1_Stop
Timer ?

Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 21:57:52
av sodjan
Japp...

Ska ju vara PWM_Start(), så klart.
Bad cut-n-paste...
Re: PWMx och PIC12F1572, men hur...?
Postat: 4 juli 2016, 22:12:42
av TomasL
Redan i MPLAB kan man ju generera config word.
Vilket är något man aldrig någonsin skall använda (dvs sätta configen i IDEn, dessutom borttaget ur MPLABX)