打印

PIC16F1937 数组操作问题 求救

[复制链接]
3906|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
牛牛特工|  楼主 | 2009-8-8 12:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 牛牛特工 于 2009-8-8 20:46 编辑

这里使用TMR1门控中断 做触摸按键
如果代码写的有问题请指正
ch变量做为数组下标来访问数组
定义了数组 touchv[8]用于存储通道8-15的数值 然而在中断中 对touchv[ch]赋值无效果
并且数组数值发生异常变化 其内容未发现什么规律
用常数作为下标访问数组元素 如touchv[0] 可以看到修改数组元素 但仍会出现数组其他元素异常变化的情况
当使用8个独立变量来存储时 则数值读取均正常
unsigned int touch_value;
unsigned int ch;
static unsigned int  touchv[8];
static unsigned int  touchv1[8];
static unsigned int  touch1,touch2,touch3,touch4,touch5,touch6,touch7,touch8;
void interrupt Touch_isr(void)
if(PIR1bits.TMR1GIF)
{
  PIR1bits.TMR1GIF=0;
  T1CONbits.TMR1ON=OFF;
  touch_value=TMR1;
//独立变量访问
  switch(ch)
  {
   case 0:touch1=touch_value;break;
   case 1:touch2=touch_value;break;
   case 2:touch3=touch_value;break;
   case 3:touch4=touch_value;break;
   case 4:touch5=touch_value;break;
   case 5:touch6=touch_value;break;
   case 6:touch7=touch_value;break;
   case 7:touch8=touch_value;break;
   default:break;
  }
//数组访问
  touchv[ch]=touch_value;
touchv1[ch]=touch_value;
  ch++;
  ch&=0x07;
  CPSCON1bits.CPSCH=8+ch;//使用电容传感8-15通道
  TMR1=0;
  T1CONbits.TMR1ON=ON;
}
}
沙发
牛牛特工|  楼主 | 2009-8-8 13:51 | 只看该作者
有趣现象 我现在又定义了一个数组
static unsigned int  touchv2[8];
然后在touchv[ch]=touch_value;后加了一句
touchv2[ch]=touch_value;
结果发现touchv2内容正确了 而touchv的内容是一如既往的让人摸不着头脑

使用特权

评论回复
板凳
yewuyi| | 2009-8-8 14:06 | 只看该作者
编译没报错,你怎么多了一个}

去掉static看看,另外touch_value本来就是变化的啊。

使用特权

评论回复
地板
牛牛特工|  楼主 | 2009-8-8 16:09 | 只看该作者

编译肯定能通过的 这是运行时看到的问题

本帖最后由 牛牛特工 于 2009-8-8 16:14 编辑

{是不小心给打上去的
楼上可能没理解我的意思
不是touchvalue 的问题 那个值是正常的 touchvalue在某范围内摆动
我是说touchv数组内的值不正确
本来touchv数组存的是8个touchvalue的值(它是应该随着touchvalue变化)

然而实际看的情况是 touchv内容与touchvalue完全搭不上关系 乱七八糟

定义了touchv2 之后 touchv2内是预期数据
最早定义的touch1- touch8 也是正常数据

使用特权

评论回复
5
牛牛特工|  楼主 | 2009-8-8 16:18 | 只看该作者
实验了下 加static和不加static 一样
另: 现在又变了  
touchv2不正常 touchv1正常了
这两个数组
总有一个内容是混乱的  
我的touchvalue正常值值是从
0x1XX 到0x2XX
非正常值 有的为零 有的高达0x8**

使用特权

评论回复
6
牛牛特工|  楼主 | 2009-8-8 16:19 | 只看该作者
三个X放一起似乎会被和谐~~

使用特权

评论回复
7
yewuyi| | 2009-8-8 16:28 | 只看该作者
软仿真看一下不就什么都知道了吗?

基本的调试手段还是要学会的,强制给赋值看看能不能成功。

使用特权

评论回复
8
yewuyi| | 2009-8-8 16:31 | 只看该作者
你的软件貌似本来就不合理。
if(i<60)
  {
   i++;
  }
  PIR1bits.TMR1GIF=0;
  T1CONbits.TMR1ON=OFF;

你至少也应该先执行:PIR1bits.TMR1GIF=0;  T1CONbits.TMR1ON=OFF;这两句把,很少有人在TIMER中断后延迟一段时间再执行这段代码的,另外,也很少有人在中断里面执行那么长的DELAY 。。。

使用特权

评论回复
9
牛牛特工|  楼主 | 2009-8-8 20:37 | 只看该作者
本帖最后由 牛牛特工 于 2009-8-8 20:49 编辑


你试试哪个软件能仿真这个片子 我是在ICD2 上调试的 MPLABSIM软仿真无法进中断 我试试直接在Main里访问吧
我的代码里哪里有delay 我不太明白你的意思 我这里不是while
if(i<60)
{
i++;
}
这不是delay 只是给主程序使用的一个标志 在此中断中并无实际意义 现将其删除做实验  
另外: 对TMR1GIF TMR1ON的操作挪到前面了 没有任何改变
您说的赋常数好像是个有效检验办法 我现在就试一下 谢谢

使用特权

评论回复
10
牛牛特工|  楼主 | 2009-8-8 20:42 | 只看该作者

实验结果

本帖最后由 牛牛特工 于 2009-8-8 20:55 编辑

我使用常数下标访问数组元素
数值可以改变 然而 其他未操作的元素也发生变化
并且数值不确定
另 对数组元素赋常数值 发现情况无改变
我将这里
touchv[ch]=touch_value;
改为了 touchv[ch]=0x55;
touchv2[ch]=0xaa;
touchv2的数组元素 确实全部变成了 0xaa
而touchv的元素 则仍是无法预知的值

使用特权

评论回复
11
牛牛特工|  楼主 | 2009-8-8 21:03 | 只看该作者
惊人消息   我把中断函数删除
仅有main函数的情况下
代码如下 未定义其他变量和函数 请指导

unsigned int  touchv[8];
unsigned int  touchv2[8];
void main(void)
{
                for(ch=0;ch<8;ch++)
                {
                        touchv[ch]=0x55;
                        touchv2[ch]=0xaa;

                }
                while(1);       
               
}
while(1)处设断点
运行结果是 touchv  10个0x0055正常全部被 touchv2 内容为 前面三个元素为零
第四个 0x0300
第五个 0x8001
第六个 0x1F1F
第七个 0x2f07
第八个 0x0004
我看过好几次 0x0300 和0x8001这两个值
几乎每次都出现

使用特权

评论回复
12
牛牛特工|  楼主 | 2009-8-8 21:18 | 只看该作者
我终于发现了规律 每当数组的首地址为0x320时 这个数组的元素 就不能正常操作

使用特权

评论回复
13
牛牛特工|  楼主 | 2009-8-8 21:27 | 只看该作者
本帖最后由 牛牛特工 于 2009-8-8 21:31 编辑

由于发现分配到0x320会出问题
我终于找到了一个解决办法
利用@定址分配数组
改为如下代码 OHYEAH 一切正常了!!!!
unsigned int  touchv[8]@ 0x220;
unsigned int  touchv2[8]@ 0x240;
unsigned char ch;

void main(void)
{
                for(ch=0;ch<8;ch++)
                {
                        touchv[ch]=0x55;
                        touchv2[ch]=0xaa;

                }
                while(1);        
               
}
但是以后可麻烦了 每个都要分配地址 自己要规划 麻烦啊

使用特权

评论回复
14
牛牛特工|  楼主 | 2009-8-8 21:42 | 只看该作者
很好 我又找到一个办法
按照如下方式 即用全局指针 局部数组 两个数组皆可正常访问
另:局部数组若定义为 static型 同样会出现刚才相同的问题
unsigned char ch;
unsigned int *ptr1,*ptr2 ;

void main(void)
{
        unsigned int  touchv[8];
        unsigned int  touchv2[8];       
        ptr1=touchv;
        ptr2=touchv2;
        for(ch=0;ch<8;ch++)
                {
                        ptr1[ch]=0x55;
                        ptr2[ch]=0xaa;

                }
                while(1);       
               
}

使用特权

评论回复
15
牛牛特工|  楼主 | 2009-8-8 22:21 | 只看该作者
本帖最后由 牛牛特工 于 2009-8-8 22:26 编辑

很好 经过试验 我找到了第三个办法
当数组大小大于16个字节时 其也不会被分配到0x320这个地址(貌似因为这里正好有16个byte空间)

我将其定义为9个元素的数组  就正常咯!! 这时候全局 或者静态局部 都没问题!!

使用特权

评论回复
16
牛牛特工|  楼主 | 2009-8-8 22:26 | 只看该作者
不管咋样还是谢谢版主!!

使用特权

评论回复
17
牛牛特工|  楼主 | 2009-8-10 09:21 | 只看该作者
本帖最后由 牛牛特工 于 2009-8-10 09:25 编辑

经多次和在多台电脑上测试
仅仅当数组大小等于 16个byte时 才会有如上问题 即
数组小于16byte 或数组大于16byte 都是正常的哦
昨天的结论不正确
如 这样时 发现无错误
unsigned char  array[15],j;
void main(void)
{
for(j=0;j<15;j++)
array[j]=0x55;
}
而这样的时候 发先数组值异常变化
unsigned char  array[16],j;
void main(void)
{
for(j=0;j<16;j++)
array[j]=0x55;
}

使用特权

评论回复
18
yewuyi| | 2009-8-10 09:25 | 只看该作者
把你用的PICC编译器软件放到我的EMAIL中,我抽空测试一下看看。

我手上的暂时还无法编译PIC16F1**系列的。

使用特权

评论回复
19
yewuyi| | 2009-8-10 09:27 | 只看该作者

使用特权

评论回复
20
牛牛特工|  楼主 | 2009-8-10 14:56 | 只看该作者
现在我在MPLAB SIM下面软仿真不了了
一仿真就程序就自动关闭了
我都是在板子上用ICD2调试
我还遇到其他的问题
没有硬件这些问题可能都发现不了

使用特权

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

本版积分规则

52

主题

618

帖子

2

粉丝