冰楓論壇

 找回密碼
 立即註冊
搜索
查看: 752|回覆: 0
打印 上一主題 下一主題

[討論] PIC32MX440F256H

[複製鏈接]

2609

主題

0

好友

999

積分

高級會員

Rank: 4

UID
373967
帖子
8835
主題
2609
精華
0
積分
999
楓幣
15
威望
976
存款
34593
贊助金額
0
推廣
0
GP
1205
閱讀權限
50
在線時間
453 小時
註冊時間
2023-1-12
最後登入
2024-11-15

2023端午節紀念勳章 2023中秋節紀念勳章 2023聖誕節紀念勳章

跳轉到指定樓層
1
發表於 2023-4-26 18:56:19 |只看該作者 |正序瀏覽
製作多通道示波器的零件清單:

PIC32MX440F256H 微控制器
128x64 黑白 OLED 顯示屏
AD9286-80 8 位 80 MSPS ADC
多路放大器
訊號開關
快速二極體
多路電位器
轉換器
滑動式電位器
電晶體


以下是 PIC32MX440F256H 微控制器腳位圖:


       +----------------------------------------+
       |        PIC32MX440F256H 腳位圖           |
       +----------------------------------------+
                _______   _______
                |       \/      |
           MCLR |1            64| VDD
        ICSPDAT |2            63| VSS
        ICSPCLK |3            62| PGED1
            RB0 |4            61| PGEC1
            RB1 |5            60| AN15/RB15
            RB2 |6            59| AN14/RB14
            RB3 |7            58| AN13/RB13
            RB4 |8            57| AN12/RB12
            RB5 |9            56| AN11/RB11
            RB6 |10           55| AN10/RB10
            RB7 |11           54| AN9/RB9
            RB8 |12           53| AN8/RB8
            RB9 |13           52| AN7/RB7
           RB10 |14           51| AN6/RB6
           RB11 |15           50| AN5/RB5
           RB12 |16           49| AN4/RB4
           RB13 |17           48| AN3/RB3
           RB14 |18           47| AN2/RB2
           RB15 |19           46| AN1/RB1
        VUSB3V3 |20           45| AN0/RB0
         VBUSON |21           44| AVDD
            VDD |22           43| AVSS
           VSS1 |23           42| RE5
            RA0 |24           41| RE4
            RA1 |25           40| RE3
            RA2 |26           39| RE2
            RA3 |27           38| RE1
            RA4 |28           37| RE0
            RA5 |29           36| VCAP
           VSS2 |30           35| VSS
            RD0 |31           34| RD7
            RD1 |32           33| RD6
                +---------------+
程式碼:

以下是 PIC32MX440F256H 微控制器的多通道示波器的程式碼
用於顯示 ADC 讀數的圖形:


#include <p32xxxx.h>
#include <plib.h>
#include <stdio.h>

#pragma config FNOSC = FRCPLL
#pragma config FPLLIDIV
#pragma config FPLLMUL = MUL_20
#pragma config FPLLODIV = DIV_2
#pragma config FPBDIV = DIV_1
#pragma config FWDTEN = OFF

#define SYS_FREQ (80000000L)
#define PB_DIV 1
#define PRESCALE 256
#define SAMPLING_RATE (SYS_FREQ/PB_DIV/PRESCALE)

#define OLED_CMD 0x00
#define OLED_DATA 0x40

void initADC(void);
void initOLED(void);
void plotWaveform(void);

unsigned char waveformBuffer[128];

int main(void)
{
    initADC();
    initOLED();
   
    while (1)
    {
        plotWaveform();
    }
   
    return 0;
}

void initADC(void)
{
    AD1PCFG = 0xFFFF;   // All pins digital
    AD1CON1 = 0x00E0;   // Auto-convert mode
    AD1CSSL = 0x0000;   // No scanning required
    AD1CON2 = 0x0000;   // No scanning required
    AD1CON3 = 0x1F00;   // Tad = 32 PBCLK cycles
    AD1CON1bits.ADON = 1;   // Turn on ADC
}

void initOLED(void)
{
    // Initialize SPI1 module
    SPI1CONbits.ON = 0;     // Disable SPI module
    SPI1CONbits.MSTEN = 1;  // Set as Master mode
    SPI1CONbits.CKE = 1;    // Clock edge select
    SPI1CONbits.SMP = 0;    // Input data sampled at middle of data output time
    SPI1CONbits.MODE16 = 0; // 8-bit mode
    SPI1CONbits.MODE32 = 0; // 8-bit mode
    SPI1CONbits.DISSDI = 0; // Enable SDI pin
    SPI1CONbits.DISSDO = 0; // Enable SDO pin
    SPI1CONbits.SSEN = 0;   // SS pin not used
    SPI1CONbits.ENHBUF = 1; // Enable enhanced buffer mode
    SPI1CONbits.MCLKSEL = 0;// Set PBCLK as SPI clock
    SPI1BRG = 0;            // Set clock divider to 1
    SPI1CONbits.ON = 1;     // Enable SPI module
   
    // Initialize OLED module
    TRISDbits.TRISD9 = 0;   // Set RD9 as output (data/command pin)
    TRISGbits.TRISG6 = 0;   // Set RG6 as output (reset pin)
    PORTGbits.RG6 = 1;      // Set OLED reset pin high
    DelayMs(1);             // Wait for OLED to stabilize
    PORTGbits.RG6 = 0;      // Set OLED reset pin low
    DelayMs(10);            // Wait for OLED to reset
    PORTGbits.RG6 = 1;      // Set OLED reset pin high
   
    // Initialize OLED display
    WriteOLEDCommand(0xAE);  // Display off
    WriteOLEDCommand(0xA1);  // Segment remap
    WriteOLEDCommand(0xDA);  // Common pads hardware: alternative
    WriteOLEDCommand(0x12);
    WriteOLEDCommand(0xC8);  // Common output scan direction:com63~com0
    WriteOLEDCommand(0D5,D4 display multiplex, D3 disable to display clock, D2~D0normal)
    WriteOLEDCommand(0x81);  // Contrast control
    WriteOLEDCommand(0xCF);
    WriteOLEDCommand(0xD9);  // Set pre-charge period
    WriteOLEDCommand(0xF1);
    WriteOLEDCommand(0xDB);  // VCOM deselect level mode
    WriteOLEDCommand(0x40);
    WriteOLEDCommand(0xA4);  // Set display mode: Reset
    WriteOLEDCommand(0xA6);  // Set display mode: Normal display
    WriteOLEDCommand(0xAF);  // Display on
}

void plotWaveform(void)
{
    int i;
   
    // Sample analog inputs
    AD1CON1bits.SAMP = 1;   // Start sampling
    DelayUs(10);            // Wait for sampling to complete
    AD1CON1bits.SAMP = 0;   // Stop sampling and start conversion
    while (!AD1CON1bits.DONE);  // Wait for conversion to complete
    int adcValues[4];
    adcValues[0] = ADC1BUF0;
    adcValues[1] = ADC1BUF1;
    adcValues[2] = ADC1BUF2;
    adcValues[3] = ADC1BUF3;
   
    // Convert ADC values to waveform buffer
    for (i = 0; i < 128; i++)
    {
        int sum = 0;
        int j;
        for (j = 0; j < 4; j++)
        {
            AD1CHSbits.CH0SA = j;   // Select analog input channel
            AD1CON1bits.SAMP = 1;   // Start sampling
            DelayUs(10);            // Wait for sampling to complete
            AD1CON1bits.SAMP = 0;   // Stop sampling and start conversion
            while (!AD1CON1bits.DONE);  // Wait for conversion to complete
            sum += ADC1BUF0;
        }
        waveformBuffer[i] = sum / 4;
    }
   
    // Display waveform on OLED
    WriteOLEDCommand(0xAE);      // Display off
    WriteOLEDCommand(0x20);      // Set memory addressing mode
    WriteOLEDCommand(0x10);      // Set horizontal addressing mode
    WriteOLEDCommand(0xB0);      // Set page start address
    WriteOLEDCommand(0x00);      // Set lower column address
    WriteOLEDCommand(0x10);      // Set higher column address
    for (i = 0; i < 128; i++)
    {
        WriteOLEDData(waveformBuffer[i]);
    }
    WriteOLEDCommand(0xAF);      // Display on
}

void WriteOLEDCommand(unsigned char command)
{
    LATDbits.LATD9 = OLED_CMD;
    while (SPI1STATbits.SPITBF); // Wait for TX buffer to be empty
    SPI1BUF = command;           // Send command
    while (!SPI1STATbits.SPIRBF);// Wait for RX buffer to be full
    char dummy = SPI1BUF;        // Discard received data
}

void WriteOLEDData(unsigned char data)
{
    LATDbits.LATD9 = OLED_DATA;
    while (SPI1STATbits.SPITBF); // Wait for TX buffer to be empty
    SPI1BUF = data;
while (!SPI1STATbits.SPIRBF);// Wait for RX buffer to be full
char dummy = SPI1BUF;        // Discard received data
}

void DelayUs(unsigned int us)
{
// Convert us to timer ticks
us *= PBCLK / 1000000;

// Use Timer 2 to generate delay
T2CONbits.TCKPS = 0;        // Set prescaler to 1
T2CONbits.T32 = 0;          // Timer 2 operates as two 16-bit timers
T2CONbits.TCS = 0;          // Use internal clock
TMR2 = 0;                   // Reset timer
PR2 = us;                   // Set period
T2CONbits.TON = 1;          // Turn on timer

// Wait for timer to expire
while (!IFS0bits.T2IF);

T2CONbits.TON = 0;          // Turn off timer
IFS0bits.T2IF = 0;          // Clear interrupt flag
}

int main(void)
{
TRISB = 0xFFFF; // Set all PORTB pins as inputs
TRISD = 0; // Set all PORTD pins as outputs
LATD = 0; // Clear all PORTD outputs

// Configure SPI1 for OLED communication
SPI1CONbits.ON = 0;         // Turn off SPI1
SPI1CONbits.MSTEN = 1;      // Master mode
SPI1CONbits.CKP = 0;        // Idle clock low
SPI1CONbits.CKE = 1;        // Data changes on falling edge
SPI1CONbits.SMP = 0;        // Sample data on rising edge
SPI1CONbits.MODE16 = 0;     // 8-bit mode
SPI1CONbits.MODE32 = 0;     // 8-bit mode
SPI1CONbits.DISSDO = 0;     // SDO1 enabled
SPI1CONbits.DISSDI = 1;     // SDI1 disabled
SPI1CONbits.SSEN = 0;       // SS1 pin not used
SPI1CONbits.ENHBUF = 0;     // Standard buffer mode
SPI1CONbits.MCLKSEL = 0;    // PBCLK used as clock source
SPI1BRG = 0;                // Maximum baud rate
SPI1CONbits.ON = 1;         // Turn on SPI1

// Configure Timer 2 for delay function
T2CONbits.ON = 0;           // Turn off Timer 2
T2CONbits.TCKPS = 0;        // Set prescaler to 1
T2CONbits.T32 = 0;          // Timer 2 operates as two 16-bit timers
T2CONbits.TCS = 0;          // Use internal clock
TMR2 = 0;                   // Reset timer
PR2 = 0xFFFF;               // Set period to maximum
T2CONbits.ON = 1;           // Turn on Timer 2

// Configure analog inputs for ADC
AD1PCFG = 0xFFFF;           // Set all pins as digital
AD1CON1bits.ADON = 0;       // Turn off ADC1
AD1CON1bits.FORM = 0;       // Integer format
AD1CON1bits.SSRC = 0b111;   // Auto-
AD1CON1bits.ASAM = 1;       // Auto-start sampling
AD1CON2bits.VCFG = 0;       // Use AVDD and AVSS as reference
AD1CON2bits.CSCNA = 1;      // Scan inputs
AD1CON2bits.SMPI = 3;       // Interrupt after 4 conversions
AD1CON2bits.BUFM = 0;       // Use 16-word buffer
AD1CON2bits.ALTS = 0;       // Always use MUXA
AD1CON3bits.ADRC = 0;       // Use PBCLK as clock source
AD1CON3bits.SAMC = 0b11111; // 31 Tad
AD1CON3bits.ADCS = 1;       // Set Tad to 2x Tpb
AD1CHSbits.CH0NA = 0;       // Use Vref- as negative input
AD1CON1bits.ADON = 1;       // Turn on ADC1

// Configure Timer 3 for PWM output
T3CONbits.ON = 0;           // Turn off Timer 3
T3CONbits.TCKPS = 0;        // Set prescaler to 1
T3CONbits.TCS = 0;          // Use internal clock
T3CONbits.TGATE = 0;        // Disable gated mode
T3CONbits.TSIDL = 0;        // Continue operation in idle mode
T3CONbits.TSYNC = 0;        // Do not sync external clock input
TMR3 = 0;                   // Reset timer
PR3 = 3999;                 // Set period to 4ms
OC1R = 0;                   // Clear duty cycle
OC1RS = 2000;               // Set initial duty cycle to 50%
OC1CONbits.OCTSEL = 1;      // Use Timer 3 for output compare
OC1CONbits.OCM = 0b110;     // PWM mode
T3CONbits.ON = 1;           // Turn on Timer 3

while (1)
{
    // Start ADC conversion
    AD1CON1bits.SAMP = 1;
    DelayUs(10);
    AD1CON1bits.SAMP = 0;
   
    // Wait for ADC conversion to complete
    while (!IFS0bits.AD1IF);
   
    // Read ADC result and display on OLED
    int i;
    for (i = 0; i < 4; i++)
    {
        char str[10];
        sprintf(str, "%04d", ADC1BUF[i]);
        DrawString(10 + i * 60, 20, str, WHITE, BLACK);
    }
   
    // Update PWM duty cycle based on ADC value
    OC1RS = ADC1BUF[0] / 4;
   
    // Clear ADC interrupt flag
    IFS0bits.AD1IF = 0;
}

return 0;
}






程式碼主要功能是使用 PIC32MX440F256H 微控制器的 ADC 模塊和 PWM 模塊。

在這段程式碼中,首先使用 ADC 模塊來採樣四個通道的模擬信號,並使用 OLED 顯示每個通道的數值。
然後,根據其中一個通道的數值,更新 PWM 模塊的佔空比,以產生 PWM 輸出信號。

具體來說,以下是每個主要設置的解釋:

AD1CON1bits.ASAM = 1;:啟用自動採樣模式,讓 ADC 自動開始採樣。
AD1CON2bits.VCFG = 0;:將 AVDD 和 AVSS 設置為 ADC 參考電壓。
AD1CON2bits.CSCNA = 1;:啟用通道掃描模式,讓 ADC 自動掃描多個通道。
AD1CON2bits.SMPI = 3;:設置中斷標誌觸發時的掃描數量,此處設置為 4。
AD1CON2bits.BUFM = 0;:使用 16 個單詞緩存。
AD1CON2bits.ALTS = 0;:始終使用 MUXA。
AD1CON3bits.ADRC = 0;:使用 PBCLK 作為 ADC 時鐘源。
AD1CON3bits.SAMC = 0b11111;:設置採樣時間,此處為 31 Tad。
AD1CON3bits.ADCS = 1;:設置 ADC 時鐘分頻,此處設置為 2x Tpb。
AD1CHSbits.CH0NA = 0;:使用 Vref- 作為負輸入。
AD1CON1bits.ADON = 1;:啟用 ADC1。
以上設置將 ADC1 設置為掃描模式,自動採樣四個通道,並將採樣結果存儲在 ADC1BUF 中。

接下來,使用 Timer 3 和 Output Compare 模塊來生成 PWM 輸出信號。
具體來說:

T3CONbits.ON = 0;:關閉 Timer 3。
T3CONbits.TCKPS = 0;:設置計時器分頻器,此處設置為 1。
T3CONbits.TCS = 0;:使用內部時鐘源。
T3CONbits.TGATE = 0;:禁用門控模式。
T3CONbits.TSIDL = 0;:在空閒模式下
收藏收藏0 推0 噓0


把本文推薦給朋友或其他網站上,每次被點擊增加您在本站積分: 1彩票
複製連結並發給好友,以賺取推廣點數
簡單兩步驟,註冊、分享網址,即可獲得獎勵! 一起推廣文章換商品、賺$$
高級模式
B Color Image Link Quote Code Smilies |上傳

廣告刊登意見回饋關於我們管群招募本站規範DMCA隱私權政策

Copyright © 2011-2024 冰楓論壇, All rights reserved

免責聲明:本網站是以即時上載留言的方式運作,本站對所有留言的真實性、完整性及立場等,不負任何法律責任。

而一切留言之言論只代表留言者個人意見,並非本網站之立場,用戶不應信賴內容,並應自行判斷內容之真實性。

小黑屋|手機版|冰楓論壇

GMT+8, 2024-11-15 21:21

回頂部