论坛风格切换切换到宽版
  • 4327阅读
  • 11回复

求一个C的数据传送 [复制链接]

上一主题 下一主题
离线XLDZZ
 
发帖
443
只看楼主 倒序阅读 0楼 发表于: 2010-02-13
最近想做个带数字滤波的v/f变换器

遇到一个问题就是c中的数据传送

如temp=0xf1;
  cunt=0x10;
  temp=0xf1-cunt;

结果好像还是temp=0xf1
离线BD7QX
发帖
301
只看该作者 1楼 发表于: 2010-02-13
你的程序太过简单,看不出问题来;你用的是什么编译器?这只个变量是怎么定义什么类型的?程序最好给完整些,这样才好分析你的问题来。
离线XLDZZ
发帖
443
只看该作者 2楼 发表于: 2010-02-13
程序如下,没有使用config是因为采用的pic12f675在pic12f67x.h中未定义

本来想在gpio2按下时,让脉冲频率变化。现在好像不行,脉冲式出来了,但改不
了频率



#include<pic.h>
#define uchar unsigned char
#define uint unsigned int
void io_reset();
void int_reset();
void delay(uint x);
uchar temp;
void main()
{
io_reset();
int_reset();
temp=0xf0;
while(1);
{      
if(gpio2==1)
  delay(16);
  if(gpio2==1)
  {
  temp=temp-0x010;
  }
}
}
void io_reset()
{
cmcon=0x07;//关比较器
ansel=0; //全部为数字io
trisio=0x02;//gp2为输入,其他为输出
gpio=0;//清gpio寄存器
}

void int_reset()
{
intcon=0xc0;
option=0xc0;
pie1=0x01;
pir1=0x00;
t1con=0x01;//启动tmr1
tmr1l=temp;
tmr1h=temp;
}


                                       


void delay(uint x)
{
     uint a,b;
     for(a=x;a>0;a--)
           for(b=110;b>0;b--);
}


void interrupt time1()
{
  if(tmr1if==1)
    {
    tmr1if=0;
    if(gpio4=1)  
      {
        gpio4=0;
        }
    else
      {
        gpio4=1;
      }
   
    if(gpio4==0)  
      {
      gpio4=1;
      }
    else
      {
      gpio4=0;
      }
    }

 
  tmr1if=0;
  tmr1l=temp;
  tmr1h=temp;
  t1con=0x01;
}
附件: vf.rar (0 K) 下载次数:58
离线BD7QX
发帖
301
只看该作者 3楼 发表于: 2010-02-13
pic的单片机我没玩过,看了你的程序发现以下两个问题,你改改看能不能用了:
void main()
{
io_reset();
int_reset();
temp=0xf0;
while(1);       ??? 看到这个“;"了吗?程序跑到这里就死循环了,去掉";"就可以往下跑了
{      
if(gpio2==1)     ???? 这里有个疑问pic的io输入是以高电平来识别的吗?一般以低电平作为输入识别要好些
  delay(16);
  if(gpio2==1)
  {
  temp=temp-0x010;
  }
}
}
离线XLDZZ
发帖
443
只看该作者 4楼 发表于: 2010-02-13
'
pic的单片机我没玩过,看了你的程序发现以下两个问题,你改改看能不能用了:
void main()
{
io_reset();
int_reset();
temp=0xf0;
while(1);       ??? 看到这个“;"了吗?程序跑到这里就死循环了,去掉";"就可以往下跑了
{      
if(gpio2==1)     ???? 这里有个疑问pic的io输入是以高电平来识别的吗?一般以低电平作为输入识别要好些
  delay(16);
  if(gpio2==1)
  {
  temp=temp-0x010;
  }
}
}
'





while(1)后面的;号去掉后也没有用,还是改不了频率。
我觉得还是数据在不同的地址中传送有问题,做电机测速仪时也遇到了这个问题
不知道是否为编译器的问题
我用的编译器是hi——tech 8.05的版本(破解版)

谢谢bd7qx的回复,美好的73送你。
离线BD7QX
发帖
301
只看该作者 5楼 发表于: 2010-02-14
你的gpio2是用高电平为输入的吗?也就是说gpio2的初态是有下拉电阻的吗?别外感觉你的中断函数里io反转的操作用了两个if互相排斥了,io反转将是个很窄的脉冲。
void interrupt time1()
{
if(tmr1if==1)
{
tmr1if=0;
if(gpio4=1)   // 这里改为 if (gpio4==1)
{
gpio4=0;
}
else
{
gpio4=1;
}
/************把下面的这段if屏蔽掉*********/
/*
if(gpio4==0)
{
gpio4=1;
}
else
{
gpio4=0;
}
*/
}


tmr1if=0;
tmr1l=temp;
tmr1h=temp;
t1con=0x01;
}
离线XLDZZ
发帖
443
只看该作者 6楼 发表于: 2010-02-14
可能是我第一次用c来写pic12f系列的单片机。
有些中断的设置没有搞对,用示波器看波形,脉冲宽度为10us。

12f675采用内部4m振荡,指令周期为1us。也就是说开机没几个周期就进入
中断,而且死在中断里了。


最大的可能是编译器不支持12系列的,附件是用汇编写的,用来产生pwm的
是可以用的。

我还是自己在看看吧。有了答案在回复吧。
附件: auto1.rar (0 K) 下载次数:54
离线BA5RW
发帖
48263
只看该作者 7楼 发表于: 2010-02-15
void interrupt time1()后面没有interrupt的序号吗?用51后面是需要类似interrupt 0的。

51中类似是:void interrupt time1()interrupt 2

不知道其他mcu的c是不是也要?
离线XLDZZ
发帖
443
只看该作者 8楼 发表于: 2010-02-15
'
void interrupt time1()后面没有interrupt的序号吗?用51后面是需要类似interrupt 0的。
51中类似是:void interrupt time1()interrupt 2
不知道其他mcu的c是不是也要?
'
pic单片机低端和中端产品(12系列和16系列)没有中端优先级控制,只能用软中端
来控制。interrupt 2----是否指用第二组工作寄存器(或者中端优先级2级),以方便数据保护。

所以不需要c51那么麻烦,但任何中断都可以引发中端。一般使用查询和软中断控制来处理。
离线BA5RW
发帖
48263
只看该作者 9楼 发表于: 2010-02-15
'
pic单片机低端和中端产品(12系列和16系列)没有中端优先级控制,只能用软中端
来控制。interrupt 2----是否指用第二组工作寄存器(或者中端优先级2级),以方便数据保护。
所以不需要c51那么麻烦,但任何中断都可以引发中端。一般使用查询和软中断控制来处理。
'
11.6.4 中断函数的实现

picc 可以实现 c 语言的中断服务程序。中断服务程序有一个特殊的定义方法:
void interrupt isr(void);
中的函数名“isr”可以改成任意合法的字母或数字组合,但其入口参数和返回参数类型
须是“void”型,亦即没有入口参数和返回参数,且中间必须有一个关键词“interrupt”。

中断函数可以被放置在原程序的任意位置。因为已有关键词“interrupt”声明,picc 在
后进行代码连接时会自动将其定位到 0x0004 中断入口处,实现中断服务响应。编译器也
实现中断函数的返回指令“retfie”。一个简单的中断服务示范函数如下:
void interrupt isr(void) //中断服务程序
{
  if (t0ie && t0if)   //判tmr0中断
  {
t0if = 0;   //清除tmr0中断标志
    //在此加入tmr0中断服务
  }
  if (tmr1ie && tmr1if) //判tmr1中断
  {
tmr1if = 0;   //清除tmr1中断标志
    //在此加入tmr1中断服务
  }
}     //中断结束并返回

例11-5 c语言中断函数举例
picc 会自动加入代码实现中断现场的保护,并在中断结束时自动恢复现场,所以编程
无需象编写汇编程序那样加入中断现场保护和恢复的额外指令语句。但如果在中断服务程
中需要修改某些全局变量时,是否需要保护这些变量的初值将由编程员自己决定和实施。

用 c 语言编写中断服务程序必须遵循高效的原则:   代码尽量简短,中断服务强调的是一个“快”字。   避免在中断内使用函数调用。虽然 picc 允许在中断里调用其它函数,但为了解决
递归调用的问题,此函数必须为中断服务独家专用。既如此,不妨把原本要写在其
它函数内的代码直接写在中断服务程序中。   避免在中断内进行数学运算。数学运算将很有可能用到库函数和许多中间变量,就
算不出现递归调用的问题,光在中断入口和出口处为了保护和恢复这些中间临时变
量就需要大量的开销,严重影响中断服务的效率。
中档系列 pic 单片机的中断入口只有一个,因此整个程序中只能有一个中断服务函数。
离线BI7LNQ
发帖
600
只看该作者 10楼 发表于: 2010-02-16
'

void interrupt time1()
{
  if(tmr1if==1)
    {
    tmr1if=0;
    if(gpio4=1)
      {
        gpio4=0;
        }
    else
      {
        gpio4=1;
      }

   
    if(gpio4==0)  
      {
      gpio4=1;
      }
    else
      {
      gpio4=0;
      }
    }
 
  tmr1if=0;
  tmr1l=temp;
  tmr1h=temp;
  t1con=0x01;
}
'

红色部分删除。你想做的是翻转电平。但是只要一组if判断就可以了。两组的话就像前面有人提到的,会形成一个非常窄的脉冲。何况你第一组if判断写错了应该是==不是=。像这种判断一般要求将常量写在前面,这样你写成if(1=gpio4)的时候,编译的时候就会报错提醒你
离线efree
发帖
554
只看该作者 11楼 发表于: 2010-02-19
if(gpio4==0)
{
gpio4=1;
}
else
{
gpio4=0;
}
}


这个地方可以这么写,简单一点吧,嘿嘿。
gpio4=~gpio4;