打印

pic AD轉換問題求救 16f676

[复制链接]
5019|24
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fangfei036|  楼主 | 2012-5-16 08:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
AD, pic, AN, dc, ADC
各位前輩,如下是我整的pic 16f676的ad轉換程序,不知咋的仿真就是看不到有採集到數據,麻煩各位前輩順道就幫我看看,謝謝了  另還有一个问题,这个16f676数据手册上没有看到有pwm的功能,不知有木有用过的前辈帮我确认下是否真的没有这个功能,如果要输出可调脉冲占空比的,是否用定时器来做? thanks
#include<pic.h>
__CONFIG (INTOSCIO & UNPROTECT & PWRTEN & BOREN & WDTDIS & MCLRDIS);
#define uchar unsigned char
#define uint unsigned int  
void adinit(void);
uint ADSTAT(uchar adnum); //ad轉換函數
void delay(char t);
int get_ad(void);
int adnum,adc_result;
void main()
{

TRISA=0X03;//RA0,RA2wei shu ru

TRISC=0X00;//RC WEI SHU RU

PORTA=0x00;

PORTC=0x00;


ADCON0=0B10000001;//右對齊,RA0通道,開啟AD模塊

ADCON1=0B00010000;//FOSC/8

ANSEL=0X01;//RA0WEI MONI SHU RU TONG DAO;

delay(5);

//PEIE=1; //SHI NENG WAI SHE ZHONG DUAN

//ADIE=1; //SHI NENG AD ZHONG DUAN

//GIE=1;  //KAI ZONG ZHONG DUAN

while(1)

{

adnum=get_ad();

if(adnum>1200) RC0=1;

else if(adnum<=120) RC0=0;


}

}
int get_ad()
{

uint ad_result;

uchar i=0;

ADCON0=0B10000001|0B00000010;//QI DONG AD

//while(ADIF);

ad_result=ADRESH;

ad_result=ad_result<<8|ADRESL;

for(i=0;i<=3;i++)

{

ad_result+=ad_result;

delay(3);

}

ad_result=ad_result/3;

return (ad_result);

}
void delay(char t)
{

int x,y;

for(x=t;x<0;x--)

for(y=120;y<0;y--);
}

相关帖子

沙发
fangfei036|  楼主 | 2012-5-16 09:02 | 只看该作者
小弟一初学者,太多太多的不懂,各位前辈有砖头的就砸过来吧

使用特权

评论回复
板凳
fangfei036|  楼主 | 2012-5-16 11:56 | 只看该作者
再顶顶,别这么快就沉了,问题还是没有解决呢

使用特权

评论回复
地板
Tinnal| | 2012-5-16 12:36 | 只看该作者
你用什么仿真呀。不会又是proteus吧?


4.0 TIMER0 MODULE
The Timer0 module timer/counter has the following
features:
• 8-bit timer/counter
• Readable and writable
• 8-bit software programmable prescaler
• Internal or external clock select
• Interrupt on overflow from FFh to 00h
• Edge select for external cloc

从上面的特性以及手册里的timer结构图来看,pic 16f676不支持PWM。因为从结构图就看出来,Timer里没有比较器这一关键部件。

看了一下你的程序,你的delay(5);是没用的,因为此前你并没有开启AD(GO/DONE在上面一条语句里头被设成0)
bit 1 GO/DONE: A/D Conversion STATUS bit
1 = A/D conversion cycle in progress. Setting this bit starts an A/D conversion cycle.
      This bit is automatically cleared by hardware when the A/D conversion has completed.
0 = A/D conversion completed/not in progress

而你在get_ad()这个函数里,虽然设了GO/DONE位,但你没有等转换结束(cleared by hardware )就去读值了。这样肯定不行麻。
建议你最起码弄个while在那等等GO/DONE位,而不是在那多加一个delay,这样你也好分辨是AD转换出问题,还是读回来的数不正确。

使用特权

评论回复
5
fangfei036|  楼主 | 2012-5-16 13:24 | 只看该作者
4# Tinnal
谢谢仁兄的耐心指点,我用的是 proteus 仿真的,请问有更好些的仿真吗?
我改下然后回去再烧写到芯片上试下,之前一直以为没有把转换的值读回来,原来压根没转换啊 欢迎前面们多提意见。
还有一个问题,为什么发现一个公司的产品怎么用这个16F676做PWM调光呢?他是怎麼做到的?

使用特权

评论回复
6
Tinnal| | 2012-5-16 13:32 | 只看该作者
本帖最后由 Tinnal 于 2012-5-16 13:44 编辑

我在这个论坛说过很多遍了,学校老师上课用用没有问题。想学单片机就不要用proteus 了,老老实实买块51开发板,学真的,另学假的。你搜索一下这个论坛,就会搜到很多于proteus OK但做不出实物的。而且PIC 16F好好好好老啦。你怎么就想用它了呢?

使用特权

评论回复
7
Tinnal| | 2012-5-16 13:40 | 只看该作者
本帖最后由 Tinnal 于 2012-5-16 13:42 编辑

5# fangfei036
“为什么发现一个公司的产品怎么用这个16F676做PWM调光呢?他是怎麼做到的?”
方式可以很多麻,我只是说Timer本身不支持PWM而已。

用Timer+程序就可以实现了。
我们据个例。
用Timer弄个10K的中断出来(Timer的周期设为0.1ms),假定我们想产生20%的占空比,输出频率为1K。则只需要在中段程序里做个计数。


if(count > 2)
     output = 1;
else if (count >= 10)
{
    output =0;
    count =0;
}


count++;




OK

使用特权

评论回复
8
fangfei036|  楼主 | 2012-5-16 13:52 | 只看该作者
7# Tinnal
谢谢Tinnal兄,如果是这样的话,就是改变定时器转入的初值来改变脉宽了是吗??我一定试试,刚刚用软件仿真了下,发现提示说ad_result 超出范围了(out of scope),我修改成了long int 的也没有用,请问这个咋整啊?

使用特权

评论回复
9
fangfei036|  楼主 | 2012-5-16 13:52 | 只看该作者
7# Tinnal
谢谢Tinnal兄,如果是这样的话,就是改变定时器转入的初值来改变脉宽了是吗??我一定试试,刚刚用软件仿真了下,发现提示说ad_result 超出范围了(out of scope),我修改成了long int 的也没有用,请问这个咋整啊?

使用特权

评论回复
10
Tinnal| | 2012-5-16 15:19 | 只看该作者
改占空比就是改上面程序的那个2,想改频率就改Timer的配置和上面程序的那个10。MCU没有“out of scope”这个标志位呀。你这个是编译错误还是那个仿真软件报的错误?
如果是编译错误,那就从程序角度找问题。
如果是仿真软件报错,那就从你的仿真文件找问题。

这么么小8位单片机你就想用long型了,你不想活了。

使用特权

评论回复
11
小马快跑| | 2012-5-16 15:44 | 只看该作者
问一下ad_result=ad_result<<8|ADRESL;这个有什么用啊?

使用特权

评论回复
12
fangfei036|  楼主 | 2012-5-16 16:23 | 只看该作者
謝謝Tinnal兄的指点,我已经有PIC的学习板了,他用的是16F877的,我觉得那个太大了,所以找了一份由中文手册的16f676来学习学习,而且看到一个别的公司产品上有这个用来做led的调光,所以想整整。Tinnal兄说的句句重点,我一会好好检测,那个out of scope 是编译报错的,指示报告了这个超出范围,初学没有意识了存储器的可贵,经您这么一点,以后我会多注意的 晚上回去用硬件试试

使用特权

评论回复
13
fangfei036|  楼主 | 2012-5-16 16:25 | 只看该作者
11# 小马快跑 小马哥 ad_result=ad_result<<8|ADRESL; 指示把两个八位的数,整合成一个十六位的而已

使用特权

评论回复
14
fangfei036|  楼主 | 2012-5-17 08:07 | 只看该作者
12# fangfei036 Tinnal兄 由於我這個編程器居然不能匹配16f676的,今天打算再用16f877來寫pwm功能,不過在昨晚在家仿真了下,DA功能正常了,計時器做的pwm模擬也可以輸出,還加入了一個外部中斷調節,單個功能實現沒問題,整合到一塊又有問題了,我今天再試試,thanks

使用特权

评论回复
15
Tinnal| | 2012-5-17 12:07 | 只看该作者
本帖最后由 Tinnal 于 2012-5-17 12:15 编辑

12# fangfei036
再次告诫你,要养成良好的习惯:
别看中文手册,看英文的!
可能你说你看不懂,那就慢慢看,多查查字典。手册的模式都一样的,看多了,就算有不会的单词也能猜到他想说什么。
这个砍你必须迈过去,因为有太多的芯片没有中文资料了,而且中文资料有很多都不是最新的,为了翻译也省略了很多的细节,不出问题还好,出了问题就找不到对应的。

http://www.microchip.com/wwwproducts/devices.aspx?ddocname=en010241
有很多的资料,非常非常好的资料。这是一份中文数据手册远远比不上的。
别外,877的Timer在硬件上就只支持PWM了,只用配几个寄存器就能用的,不用再去用中断来实现。用中断实现不旦频率做不高,而且还太过于占CPU时间了,单纯做个调光等还好,要还想做其他的功能就有点不随心了。

使用特权

评论回复
16
fangfei036|  楼主 | 2012-5-18 11:18 | 只看该作者
15# Tinnal
Tinnal兄,谢谢你的耐心教导,我一定会多看多查英文资料,之前觉得看英文的太慢了点,所以想找一个有中文资料的芯片先学下。谢谢您介绍的网址,很不错,今天我用16f877写好了PWM的程序,占空比也可以调了,就是我个想法,想问问怎么去实现:
我想再输入电压在4-6v之间,电流是恒流不变的,怎么设置反馈,怎么个编程思路啊?

使用特权

评论回复
17
Tinnal| | 2012-5-18 13:00 | 只看该作者
16# fangfei036 不明白你意思,你是想用单片机采集这个电压(电流既然是恒流,就直接知道了),还是想用单片机输出这个恒流?
你于明白一点吧。

使用特权

评论回复
18
fangfei036|  楼主 | 2012-5-18 13:20 | 只看该作者
17# Tinnal
不好意思,我表达的不是很清楚,我的意思是我输出的pwm信号,然后经过一个三极管,或者mos管,还有一个电感,组成降压的电路,让pwm输出的信号,来控制mos管的通断,从而在一定电压范围内,让输出的电流基本稳定。所以,我要通过什么方法来控制让经过led的电流基本恒定(在一点电压范围内)不知道我这样表达能不能懂我的意思。

使用特权

评论回复
19
Tinnal| | 2012-5-18 13:30 | 只看该作者
这个电流你要求可调吗?如果是一个定值,那就不用单片机了,直接用电路搭恒流源就行。如果你不旦想恒流,而且单片机还能控制这个恒流的大小,那你可以把把PWM信号通过积分网络变成对应的电压(或直用DA完成),然后进行V-I转换。

使用特权

评论回复
20
Tinnal| | 2012-5-18 13:35 | 只看该作者
你可以搜一下,数据电流源,方案很多,不给你贴出来的。自己搜索一下吧。例如:
http://sti.hust.edu.cn/chengguo/skzldy_llz.htm
http://wenku.baidu.com/view/e33c73bcc77da26925c5b0fb.html
等等。
通过PWM实现的也有,如:
http://www.21ic.com/app/mcu/201109/93126.htm

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:技术力量,决定上层建筑

2

主题

345

帖子

3

粉丝