標(biāo)題:
STC15單片機(jī)采樣電壓控制調(diào)整PWM信號(hào)的占空比,改變外部電壓占空比無(wú)變化
[打印本頁(yè)]
作者:
胖虎V587
時(shí)間:
2022-7-5 11:44
標(biāo)題:
STC15單片機(jī)采樣電壓控制調(diào)整PWM信號(hào)的占空比,改變外部電壓占空比無(wú)變化
P1.0口模擬量輸入 P3.5口 PWM信號(hào)輸出
求大神指導(dǎo)下 應(yīng)該是我的程序沒(méi)有嵌套上占空比 求賜教
單片機(jī)源程序如下:
#include <reg51.h>
#include "intrins.h"
#define FOSC 10240000L
#define BAUD 9600
typedef unsigned char BYTE; //這是重新定義一個(gè)新的變量類(lèi)型byte
typedef unsigned int WORD; //定義了一個(gè)unsigned int的同義詞,名字為WORD
#define URMD 0 //0:使用定時(shí)器2做波特率發(fā)生器
//1:使用定時(shí)器1的模式0(16位自動(dòng)重載模式)作為波特率發(fā)生器
//2:使用定時(shí)器1的模式2(8位自動(dòng)重載模式)作為波特率發(fā)生器
sfr T2H = 0xd6; //定時(shí)器2高8位
sfr T2L = 0xd7; //定時(shí)器2低8位
sfr ADC_CONTR=0xBC; //定義ad轉(zhuǎn)換電源,周期,標(biāo)致,開(kāi)啟,轉(zhuǎn)換口,數(shù)據(jù)存儲(chǔ)位置
sfr ADC_RES=0xBD; //定義轉(zhuǎn)換完畢數(shù)據(jù)高高八位數(shù)據(jù)位置
sfr ADC_LOW2=0xBE; //定義轉(zhuǎn)換完畢的低2位數(shù)據(jù)存放位置
sfr P1ASP=0x9D; //定義ad轉(zhuǎn)換的總開(kāi)關(guān)位置
sfr CLK_DIV=0x97; //定義時(shí)鐘分頻寄存器地址
/*ADC操作定義常量*/
#define ADC_POWER 0x80 //ADC的電源控制位,打開(kāi),10000000
#define ADC_FLAG 0x10 //ADC完成標(biāo)志,10000,一定要軟件清零
#define ADC_START 0x08 //ADC的啟動(dòng)控制點(diǎn),1000,開(kāi)始轉(zhuǎn)換
#define ADC_SPEEDLL 0x00 //540 clocks,00,,00,540個(gè)時(shí)鐘周期轉(zhuǎn)換一次
#define ADC_SPEEDL 0x20 //360 clocks,100000,01
#define ADC_SPEEDH 0x40 //180 clocks,1000000,10
#define ADC_SPEEDHH 0x60 //90 clocks,1100000,11
void InitUart(); //初始化Uart,通用異步接收器/發(fā)送器,就是通常所說(shuō)的串行口,
void SendData(BYTE dat); //byte=char
void delay_ms(WORD n); //word=int
void InitADC();
BYTE ch = 0; //ADC通道號(hào),指定p1.0作為A/D輸入來(lái)用
/*PWM操作定義常量*/
#define PWM_DUTY 512 //定義PWM的周期,數(shù)值為時(shí)鐘周期數(shù),假如使用10.24MHZ的主頻,則PWM頻率為10240/512kHZ.
#define PWM_HIGH_MIN 32 //限制PWM 輸出的最小占空比. 用戶(hù)請(qǐng)勿修改.
#define PWM_HIGH_MAX(PWM_DUTY-PWM_HIGH_MIN) //限制PWM 輸出的最大占空比.
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sfr P3M1 = 0xB1; //1011 0001
sfr P3M0 = 0xB2; //1011 0010
sfr AUXR = 0xBE; // 10 00 11 10
sfr INT_CLKO = 0xBF; // 10 00 11 11
BYTE GBTADCResult(BYTE ch);
sbit P_PWM = P3*5; //定義PWM 輸出引腳.
u16 pwm; //定義PWM 輸出高電平的時(shí)間的變量. 用戶(hù)操作PWM 的變量.
u16 PWM_high,PWM_low; //中間變量,用戶(hù)請(qǐng)勿修改.
void delay_ms(unsigned char ms);
void LoadPWM(u16 i);
/********************主函數(shù)**************************/
void main(void)
{
P_PWM = 0; //中斷過(guò)程中裝載低電平
P3M1 &=~(1<<5); //P3.5設(shè)置為推挽輸出
P3M0 |= (1<<5); //p3口為準(zhǔn)雙向模式
TR0 = 0; //停止計(jì)時(shí)器T0計(jì)數(shù),TCON
BT0 = 1; //允許T0溢出中斷,IE
PT0 = 1; //高優(yōu)先級(jí)中斷,IP
TMOD &=~0x03; //工作模式,0:16位自動(dòng)重裝,~0x03=11111100,
//與運(yùn)算這保證后兩位一直為零,16位自動(dòng)重裝 將RL_THO和RL_TLO分別自動(dòng)裝入THO和TLO;
AUXR |= 0x80; //1T;10000000,定時(shí)器 0,不分頻
TMOD &=~0x04; //定時(shí),~0x04=11111011,與運(yùn)算這保證后第三位一直為零,
//即保證定時(shí)器 0 當(dāng)作定時(shí)器而不是計(jì)數(shù)器
INT_CLKO|= 0x01; //輸出時(shí)鐘,或運(yùn)算保證最后一位一定是1,即運(yùn)行輸出
TH0 = 0; //定時(shí)器 0 高八位為零
TL0 = 0; //定時(shí)器 0 低八位為零
TR0 = 1; //開(kāi)始運(yùn)行,允許定時(shí)器 0 開(kāi)始計(jì)數(shù)
EA = 1; //cpu開(kāi)放中斷,中斷程序?qū)?6為PWM_high和PWM_low 的高8位和低8位分別賦給TH0和TL0;
pwm = PWM_DUTY*0.4678; //給PWM 一個(gè)初值
LoadPWM(pwm); //計(jì)算PWM 的高電平時(shí)間和低電平時(shí)間然后通過(guò)中斷將高8位和低8位分別賦給TH0和TL0
delay_ms(800);
InitADC(); //初始化ADC
}
while(1)
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL |ADC_START | ch;
_nop_();
_nop_();
_nop_();
_nop_(); //等待4個(gè)nop
while(!(ADC_CONTR&ADC_FLAG)); //等待ADC轉(zhuǎn)換完成
if((ADC_RES*4+ADC_LOW2)<507)
pwm=PWM_DUTY*0.4678571
if((ADC_RES*4+ADC_LOW2)>531)
pwm=PWM_DUTY*0.4678571*531.948/(ADC_RES*4+ADC_LOW2);
LoadPWM(pwm);
delay_ms(8);
}
}
//=======================================================================
//函數(shù):voiddelay_ms(unsigned char ms)
//描述:延時(shí)函數(shù).
//參數(shù):ms,要延時(shí)的 ms 數(shù),這里只支持1~255ms,自動(dòng)適應(yīng)主時(shí)鐘.
=======================================================================
void delay_ms(unsigned char ms)
{
unsigned int i;
do{
i = POSC / 13000;
while(-i);
}while(-ms);
}
/****************計(jì)算PWM重裝值函數(shù)*******************/
void LoadPWM(u16 i)
{
u16 j;
if(i>PWM_HIGH_MAX) i = PWM_HIGH_MAX; //如果寫(xiě)入大于最大占空比數(shù)據(jù),則強(qiáng)制為最大占空比.
if(i<PWM_HIGH_MIN) i = PWM_HIGH_MIN; //如果寫(xiě)入小于最小占空比數(shù)據(jù),則強(qiáng)制為最小占空比.
j = 65536UL - PWM_DUTY + i; //計(jì)算PWM 低電平時(shí)間
i = 65536UL - i; //計(jì)算PWM 高電平時(shí)間
BA = 0;
PWM_high = i; //裝載PWM 高電平時(shí)間
PWM_low = j; //裝載PWM 低電平時(shí)間
EA = 1;
}
/*********************Timer0 中斷函數(shù)************************/
void timer0_int (void) interrupt 1
{
if(P_PWM)
{
TH0= (u8)(PWM_low>>8); //如果是輸出高電平,則裝載低電平時(shí)間,即TH0等于PWM_low的高八位
//(U8)為強(qiáng)制取低八位
TL0= (u8)PWM_low;
}
else
{
TH0= (u8)(PWM_high>>8); //如果是輸出低電平,則裝載高電平時(shí)間.
TL0= (u8)PWM_high;
}
}
/*-----------------------------
初始ADC函數(shù)
-----------------------------*/
void InitADC( )
{
P1ASF = 0x01; //設(shè)置P1口為模擬輸入端口
ADC_RES = 0; //清除先前的結(jié)果
ADC_LOW2 = 0; //清除先前的結(jié)果
ADC_CONTR = ADC_POWER | ADC_SPEEDLL |ADC_START | ch;
delay_ms(2); //ADC上電并延遲
}
作者:
胖虎V587
時(shí)間:
2022-7-5 11:50
求大佬指點(diǎn)下 能調(diào)通 必定感謝
作者:
wulin
時(shí)間:
2022-7-5 17:40
P1.0口模擬量輸入 P1.1口默認(rèn)CCP0/PWM信號(hào)輸出。用8位ADC結(jié)果直接或取反(按實(shí)際需求)賦值CCAP0H寄存器。以下是基本構(gòu)架。
#include <STC15F2K60S2.H>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
//宏定義ADC的操作命令
#define ADC_POWER 0x80 //ADC power control dit (宏定義ADC電源控制位)1000 0000
#define ADC_START 0x08 //ADC start control dit (宏定義ADC啟動(dòng)控制位)0000 1000
#define ADC_FLAG 0x10 //ADC complete flag (宏定義ADC完成標(biāo)志位) 0001 0000
#define ADC_SPEEDLL 0x00 //420 clocks (宏定義420時(shí)鐘)速度控制 0000 0000
/*-------------------------------
延時(shí)程序(11.0592MHz 1T)
-------------------------------*/
void delayms(uint k)
{
uint i,j;
for(i=k;i>0;i--)
for(j=1150;j>0;j--);
}
/*-----------------------------------------------------------------------------
InitPWM
-----------------------------------------------------------------------------*/
void PWM_Init(void)
{
CCON = 0; //初始化PCA控制寄存器
CL = 0; //復(fù)位PCA寄存器
CH = 0; //復(fù)位PCA寄存器
CMOD = 0x0E; //設(shè)置PCA時(shí)鐘源,PWM頻率=11.0592MHZ/8/256=5.400KHZ 185us
PCA_PWM0 = 0x00; //PCA模塊0工作于8位PWM
CCAP0H = CCAP0L = 0xFF; //PWM0的占空比為0%
CCAPM0 = 0x42; //允許CCP0腳用作脈寬調(diào)節(jié)輸出
CR = 1; //PCA定時(shí)器開(kāi)始工作
}
/*-----------------------------------------------------------------------------
InitADC 初始化ADC
-----------------------------------------------------------------------------*/
void InitADC(void)
{
P1ASF=0x01; //設(shè)置P1的0通道端口作為模擬輸入
ADC_RES=0; //清除ADC_RES存儲(chǔ)器以前的結(jié)果
ADC_CONTR=ADC_POWER|ADC_SPEEDLL;//ADC 開(kāi)啟電源、轉(zhuǎn)換速度 1000 0000
delayms(1); //上電延時(shí)1ms
}
/*----------------------------------------------------------------------------
Get ADC Result(獲取ADC結(jié)果)
----------------------------------------------------------------------------*/
uchar Read(uchar CHA) //獲取ADC結(jié)果
{
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|CHA|ADC_START;//啟動(dòng)轉(zhuǎn)換1000 1000
_nop_(); //延時(shí)確保正確讀到ADC_CONTR寄存器的值
_nop_();
_nop_();
_nop_();
while(!(ADC_CONTR & ADC_FLAG)); //等待ADC轉(zhuǎn)換完成
ADC_CONTR &=~ADC_FLAG; //清完成標(biāo)志置位
return ADC_RES; //返回8位ADC結(jié)果
}
void main()
{
P1M0 = 0x02;//P1.1推挽
P1M1 = 0x01;//P1.0高阻
P3M0 = 0x00;
P3M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
PWM_Init();
InitADC();
while(1)
{
CCAP0H = Read(0);
// delayms(1);
}
}
復(fù)制代碼
作者:
人工置頂員
時(shí)間:
2022-7-13 15:57
頂一下
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1