Microchip
直播中

翁愿冠

7年用户 240经验值
私信 关注
[问答]

利用两个16位定时器寄存器作为32位定时器来编码毫秒延迟功能

大家好,我是微控制器和微芯片的初学者。我试图在我的dsPIC33上编程一个延迟函数,以便等待一个以毫秒为单位的指定时间,以进行去绑定、验证时钟配置等。我遇到一个问题,我相信它与我的定时器寄存器或定义多少cl的整数变量的溢出有关。MyConfigureOscillator()函数应该创建25MIPS的Fcy。我的timer4配置有预缩放器256。因此,对于单个毫秒延迟,我需要等待:25000000/(256*1000)“counts”=1ms97.65Timer4“counts”=1msThe Timer4重新执行以获得X毫秒的等待,等待直到Timer4+Timer5达到97*X。我认为在我的比较变量声明中发生了一个问题:uint32_T.=(uint32_T)(97*.);在调试期间的变量屏幕中,这个比较变量包含0x0000000000,它告诉我它的32位宽。调用函数DelayMs(1000)时,比较变量包含十进制值31464。我认为这是溢出的,但我不知道为什么。此时,我正在考虑只拆卸一个简单的nop()或while循环,这对于确定时钟周期没有帮助,以便更容易地设置延迟函数。这是我到目前为止的代码:main.csystem.csystem.hMicrocontroller:dsPIC33EP256MC506开发板:MCLV-2程序员:真正的ICEC编译器:MPLAB X 3.45对此的任何建议或帮助都非常感谢!我正在与另一个新用户KPATEL0同时在BLDC控制项目上工作。

以上来自于百度翻译


      以下为原文

    Hello All,

I am a beginner with microcontrollers and microchip. I am trying to program a delay function on my dsPIC33 to wait a specified time in milliseconds for debouncing, validating clock configuration, etc.

I'm experiencing an issue which I believe to be associated with overflows with either my timer register or my integer variable which defines how many clock cycles to wait until a millisecond has passed.

My ConfigureOscillator() function should be creating a Fcy of 25MIPS.
My Timer4 is configured with a pre-scaler of 256.

Therefore, for a single millisecond delay I need to wait:

25,000,000 / (256 * 1000) "counts" = 1 ms
97.65 "counts" of Timer4 = 1 ms
Therefore to obtain a wait of X milliseconds, wait until Timer4 + Timer5 reaches 97 * X.

I think an issue is occurring in my declaration of my compare variable:
uint32_T compare = (uint32_T) (97 * delay);

In the variables screen during debugging this compare variables contains 0x 0000 0000 to begin with, which tells me its 32 bits wide. Upon calling the function delayMS(1000); the compare variable contains decimal value 31464. I think this is overflowing but I do not know why.

At this point I'm considering just disassembling a simple nop() or while loop that does nothing to determine the clock cycles for an easier way of setting up a delay function.

Here is my code thus far:

main.c
const unsigned int PWM_STATE1_CLKW[6] = {0xC600,0xC700,0xC500,0xC500,0xC700,0xC600};
const unsigned int PWM_STATE2_CLKW[6] = {0xC700,0xC600,0xC600,0xC700,0xC500,0xC500};
const unsigned int PWM_STATE3_CLKW[6] = {0xC500,0xC500,0xC700,0xC600,0xC600,0xC700};

#include
#include "system.h"
#include "user.h"

/****************************CONFIGURATION****************************/
void Delay_us(unsigned int);
void Delay_ms(unsigned int);

int ADCValue, i;

/*=======================================================================*
* Fixed width word size data types: *
* int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers *
* uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers *
* real32_T, real64_T - 32 and 64 bit floating point numbers *
*=======================================================================*/
typedef signed char int8_T;
typedef unsigned char uint8_T;
typedef int int16_T;
typedef unsigned int uint16_T;
typedef long int32_T;
typedef unsigned long uint32_T;
typedef float real32_T;
typedef double real64_T;

int main(void) {

    ConfigureOscillator();
    Init_Ports();
      
    while(1)
    {
         
        LATDbits.LATD5 = 1; //make LED pin high
        Delay_ms(10);
        LATDbits.LATD5 = 0; //make LED pin low
        Delay_ms(1000);
    }
}

// DELAY UP TO 2600 MICROSECONDS
void Delay_us(unsigned int delay)
{
    TMR2 = 0; // Resetting timer 2
T2CONbits.TON = 1; // Start timer 2
    while(TMR2 < (25 * delay))
        nop();
    T2CONbits.TON = 0;
}

void Delay_ms(unsigned int delay) {
    TMR4 = 0;
    TMR5HLD = 0;
    T4CONbits.TON = 1; // Start timer 4+5
      
    uint32_T compare = (uint32_T) (97 * delay);
    uint32_T tmp;
   
    while((TMR5HLD | TMR4 << 16) < compare)
        tmp = (TMR5HLD | TMR4 << 16);
        nop();
   
    T4CONbits.TON = 0;
}

/*********************************************************************
Function: void __attribute__((interrupt, no_auto_psv)) _T1Interrupt (void)

PreCondition: None.

Overview: Half-second heartbeat monitor
        
********************************************************************/
void __attribute__((interrupt, no_auto_psv)) _T1Interrupt (void)
{
    LATDbits.LATD6 = 1; //make LED pin high
    Delay_ms(10);
    LATDbits.LATD6 = 0; //make LED pin low
   
    IFS0bits.T1IF = 0;
}



system.c
/******************************************************************************/
/* Files to Include */
/******************************************************************************/

/* Device header file */
#include

#include /* For uint16_t definition */
#include /* For true/false definition */

#include "system.h" /* variables/params used by system.c */

/******************************************************************************/
/* System Level Functions */
/* */
/* Custom oscillator configuration funtions, reset source evaluation */
/* functions, and other non-peripheral microcontroller initialization */
/* functions get placed in system.c. */
/* */
/******************************************************************************/

/* Refer to the device Family Reference Manual Oscillator section for
information about available oscillator configurations. Typically
this would involve configuring the oscillator tuning register or clock
switching using the compiler's __builtin_write_OSCCON functions.
Refer to the C Compiler for PIC24 MCUs and dsPIC DSCs User Guide in the
compiler installation directory /doc folder for documentation on the
__builtin functions.*/

/* TODO Add clock switching code if appropriate. An example stub is below. */
void ConfigureOscillator(void) {
   
    // Fosc = 8 MHz * (M / (N1 * N2)
    // Fcy = Fosc / 2
   
    // Fosc = 50,000,000 Hz
    // Fcy = 25,000,000 Hz
   
    PLLFBD = 0x0030; /* M = 50 default */
    CLKDIVbits.PLLPOST = 1; /* N1 = 2 default */
    CLKDIVbits.PLLPRE = 0; /* N2 = 4 default */
    OSCTUN = 0; // FRC OSCILLATOR TUNING REGISTER
                                    // Center frequency (7.37 MHz nominal)
   
    /* Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0x3) */
    __builtin_write_OSCCONH(0x03);
    __builtin_write_OSCCONL(0x01);
   
    while (OSCCONbits.COSC != 0x3);
    while (_LOCK == 0); /* Wait for PLL lock */
        
}

void Init_Ports(void) {
    //Timers initialization
//Timer 1
TMR1 = 0; // Resetting timer 1
    PR1 = (FCY / (256 * 2));// overflows at a rate of 2 Hz
    T1CON = 0x8030; // internal Tcy*256
         
//Timer 4&5
    T4CON = 0x0038; //32 bit timer, pre-scaler of 256
    TMR4 = 0; // LSB
    T4CONbits.TSIDL = 0; // allow counter to increment while idle
    TMR5HLD = 0; // MSB
   
    //IPC0bits.T1IP = 5; // Set Timer 1 Interrupt Priority Level
    IFS0bits.T1IF = 0; // Clear Timer 1 Interrupt Flag
    IEC0bits.T1IE = 1; // Enable Timer1 interrupt
}

void nop(void) {
    __asm__ volatile ("nop");
}


system.h
/******************************************************************************/
/* System Level #define Macros */
/******************************************************************************/
#include
#include "p33EP256MC506.h"
/* TODO Define system operating frequency */

/* Microcontroller MIPs (FCY) */
#define SYS_FREQ 50000000L
#define FCY SYS_FREQ/2

/******************************************************************************/
/* System Function Prototypes */
/******************************************************************************/

/* Custom oscillator configuration funtions, reset source evaluation
functions, and other non-peripheral microcontroller initialization functions
go here. */

void ConfigureOscillator(void); /* Handles clock switching/osc initialization */
void Init_Ports(void);
void nop(void);

Microcontroller: dsPIC33EP256MC506
Dev Board: MCLV -2
Programmer: REAL ICE
Compiler: MPLAB X 3.45

Any advice or assistance with this is greatly appreciated! FYI I'm working concurrently on a BLDC control project with another new user, kpatel0.

回帖(9)

李天竹

2019-6-14 08:58:22
转换到

以上来自于百度翻译


      以下为原文

    Change
 
uint32_T compare = (uint32_T) (97 * delay);
 
to
 
uint32_T compare = 97 * (uint32_T)delay;
举报

李维兴

2019-6-14 09:13:06
…或

以上来自于百度翻译


      以下为原文

    ... or to
uint32_T compare = 97UL * delay;
举报

李牧喜

2019-6-14 09:20:30
修改,比较:正确地允许比较保持值97000十进制。但是,现在的问题是,tmp没有正确地保存TMR4和TMR5HLD的值。我拍了一张屏幕截图给你们看我在看什么,但是很明显我的访问被拒绝上传……Access Denied你们没有权限访问“http://www..hip.com/for./upload.aspx?”参考文献#18.6f5ffea5.1478628121.2e9710(文件大小小于200kB)所以我将告诉你寄存器的值。tmp=33226小数=0x000081CATMR5HLD=130小数TMR4=33226小数。作为tmp的两个LSBytes的p和TMR4不能正常工作。tmp=(TMR5HLD|TMR4<<16);//将TMR5HLD值附加到MSBytes以及将TMR4附加到LSBytes有什么想法吗?

以上来自于百度翻译


      以下为原文

    Well, modifying compare to:
 
uint32_T compare = 97UL * delay; 
Correctly allows compare to hold the value 97000 decimal. However, now the issue is that tmp is not correctly holding the values of both TMR4 and TMR5HLD.
 
I took a screenshot to show you guys what I'm seeing, but apparently my access is denied to upload... 
Access Denied

You don't have permission to access "http://www.microchip.com/forums/upload.aspx?" on this server.
Reference #18.6f5ffea5.1478628121.2e9710
 
(The file size is less than 200kB)
 
So instead, I'll tell you the values of the registers.
 
tmp = 33226 decimal = 0x 000081CA
TMR5HLD = 130 decimal
TMR4 = 33226 decimal
 
So I think my append code (that attempts to set TMR5HLD as the MSB two bytes of tmp and TMR4 as two LSBytes of tmp) is not working correctly.
 
tmp = (TMR5HLD | TMR4 << 16); // Append TMR5HLD value to the MSBytes and TMR4 to the LSBytes
 
Any ideas? 
 
 
举报

王焕树

2019-6-14 09:33:33
您似乎没有想到C使用操作数的类型而不是目的地的类型进行计算。

以上来自于百度翻译


      以下为原文

    tmp = (TMR5HLD | (uint32_T)TMR4 << 16); // Append TMR5HLD value to the MSBytes and TMR4 to the LSBytes
You don't seem to have got the concept that C does calculations using the type of the operands, not the type of the destination.
 
举报

更多回帖

发帖
×
20
完善资料,
赚取积分